|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1998.
//
// File: tablecol.hxx
//
// Contents: Column descriptions used by CLargeTable.
//
// Classes: CColumnMasterDesc
// CTableColumn
//
// CColumnMasterArray
// CTableColumnArray
//
// CColumnMasterSet
// CTableColumnSet
//
// History: 15 Sep 94 AlanW Split out from coldesc.hxx
// 12 Feb 95 AlanW Updated fields and accessors in
// CTableColumn for OLE-DB phase III
//
//--------------------------------------------------------------------------
#pragma once
class CTableVariant; class PVarAllocator; class CCompressedCol; class SSortKey;
#include <pidmap.hxx>
//+-------------------------------------------------------------------------
//
// Class: CColumnMasterDesc
//
// Purpose: A description of a column which is known to a table
// because it is a bound output column, a computed column,
// or a column in a sort key.
//
// Interface:
//
// Notes:
//
//--------------------------------------------------------------------------
class CColumnMasterDesc { friend class CColumnMasterSet;
public: CColumnMasterDesc(PROPID PropIdent = 0, VARTYPE DatType = VT_EMPTY); CColumnMasterDesc(SSortKey& rSortKey); ~CColumnMasterDesc();
void SetCompression( CCompressedCol* pCompr, PROPID SharedID = 0);
void SetComputed(BOOL fComputed) { _fComputedProperty = fComputed; }
void SetUniform(BOOL fUniform) { _fUniformType = fUniform; }
void SetNotVariant(BOOL fNotVariant) { _fNotVariantType = fNotVariant; }
BOOL IsCompressedCol() const { return 0 != _pCompression; }
CCompressedCol * GetCompressor() const { return _pCompression; }
PROPID GetCompressMasterId() const { return _CompressMasterID; }
PROPID PropId; // Property ID in table
VARTYPE DataType; // most restrictive variant type in which
// all known values can be expressed.
VARTYPE _PredominantType; // most frequently occuring variant type
USHORT _cbData; // required width in segment row data
int _fComputedProperty:1; // TRUE if generated column. In this
// case, PropId gives a special prop. ID
int _fUniformType:1; // TRUE if all data are of type
// _PredominantType
int _fNotVariantType:1; // TRUE if it is absolutely known that
// the type cannot vary (e.g., system
// properties, some computed properties)
private: CCompressedCol* _pCompression; // global compressor
PROPID _CompressMasterID; // if !0, shared compression
};
//+-------------------------------------------------------------------------
//
// Class: CTableColumn
//
// Purpose: A description of a column stored in a table segment.
// Also used for transfer of data between the table and
// rowset, and for describing the format of row buffers
// in the rowset.
//
// Interface:
//
//--------------------------------------------------------------------------
class CTableColumn { public:
enum StoreParts { StorePartValue = 0x1, StorePartStatus = 0x2, StorePartLength = 0x4, };
enum StoreStatus { StoreStatusOK = 0, StoreStatusDeferred = 1, StoreStatusNull = 2, };
CTableColumn( PROPID propid = 0, VARTYPE type = VT_NULL ): PropId( propid ), _obValue( 0 ), _cbValue( 0 ), _obStatus( 0 ), _obLength( 0 ), _usStoreParts( 0 ), _StoreAsType( type ), _PredominantType( type ), _fUniformType( TRUE ), _pCompression( 0 ), _fGlobalCompr( FALSE ), _CompressMasterID( 0 ), _fSpecial( FALSE ), _fPartialDeferred( FALSE ) { }
CTableColumn( CTableColumn & src ): PropId( src.PropId ), _obValue( 0 ), _cbValue( 0 ), _obStatus( 0 ), _obLength( 0 ), _usStoreParts( 0 ), _StoreAsType( src._StoreAsType ), _PredominantType( src._PredominantType ), _fGlobalCompr( src._fGlobalCompr ), _fUniformType( src._fUniformType ), _pCompression( 0 ), _CompressMasterID( src._CompressMasterID ), _fSpecial( FALSE ), _fPartialDeferred( src._fPartialDeferred ) { if ( _fGlobalCompr ) { _pCompression = src._pCompression; _obValue = src._obValue; _cbValue = src._cbValue; _obLength = src._obLength; _obStatus = src._obStatus; Win4Assert( src.StorePartStatus & src._usStoreParts ); _usStoreParts = ( StorePartValue | StorePartStatus ); } }
~CTableColumn( );
PROPID GetPropId() const { return PropId; }
void SetPropId( PROPID val ) { PropId = val; }
void SetGlobalCompressor( CCompressedCol* pCompr, PROPID SharedID = 0) { _pCompression = pCompr; _CompressMasterID = SharedID; _fGlobalCompr = TRUE; }
void SetLocalCompressor( CCompressedCol * pCompr, PROPID SharedId = 0 ) { _pCompression = pCompr; _CompressMasterID = SharedId; _fGlobalCompr = FALSE; }
USHORT GetValueOffset() const { return _obValue; }
USHORT GetValueSize() const { return _cbValue; }
USHORT GetStatusOffset() const { return _obStatus; }
size_t GetStatusSize() const { return sizeof (BYTE); }
USHORT GetLengthOffset() const { return _obLength; }
size_t GetLengthSize() const { return sizeof (ULONG); }
VARTYPE GetStoredType() const { return _StoreAsType; }
CCompressedCol * GetCompressor() const { return _pCompression; }
BOOL IsCompressedCol() const { return 0 != _pCompression; }
BOOL IsGlobalCompressedCol() const { return _fGlobalCompr; }
PROPID GetCompressMasterId() const { return _CompressMasterID; }
// Copy a column from table to table or to row buffer
DBSTATUS CopyColumnData( BYTE * pbDstRow, CTableColumn const & rDstColumn, PVarAllocator & rDstPool, BYTE * pbSrcRow, PVarAllocator & rSrcPool);
// Create a CTableVariant from from buffered data
BOOL CreateVariant( CTableVariant & rVarnt, BYTE * pbSrc, PVarAllocator & rSrcPool) const;
void SetValueField(VARTYPE vt, USHORT obValue, USHORT cbValue) { _StoreAsType = vt; _obValue = obValue; _cbValue = cbValue; _usStoreParts |= StorePartValue; }
void SetStatusField(USHORT obStatus, USHORT cbStatus) { Win4Assert(cbStatus == sizeof (BYTE)); _obStatus = obStatus; _usStoreParts |= StorePartStatus; }
void SetLengthField(USHORT obLength, USHORT cbLength) { Win4Assert(cbLength == sizeof (ULONG)); _obLength = obLength; _usStoreParts |= StorePartLength; }
BOOL IsValueStored() const { return _usStoreParts & StorePartValue; } BOOL IsStatusStored() const { Win4Assert( _usStoreParts & StorePartStatus ); return TRUE; } BOOL IsLengthStored() const { return _usStoreParts & StorePartLength; } StoreStatus GetStatus( const BYTE * pb ) const { Win4Assert( IsStatusStored() );
return (StoreStatus) ( * ( pb + GetStatusOffset() ) ); } BOOL IsDeferred(BYTE *pb) const { Win4Assert( IsStatusStored() );
return ( StoreStatusDeferred == GetStatus( pb ) ); }
inline BOOL IsPartialDeferred() const { return _fPartialDeferred; }
BOOL IsNull(BYTE *pb) const { Win4Assert( IsStatusStored() );
return ( StoreStatusNull == GetStatus( pb ) ); }
ULONG GetLength(BYTE *pb) const { Win4Assert( IsLengthStored() );
return * (ULONG *) ( pb + GetLengthOffset() ); }
void SetStatus(BYTE *pb, StoreStatus stat) const { Win4Assert( IsStatusStored() );
* (pb + GetStatusOffset() ) = stat; }
void SetLength( BYTE *pb, ULONG cb ) const { Win4Assert( IsLengthStored() );
* (ULONG *) (pb + GetLengthOffset() ) = cb; }
void Marshall( PSerStream & stm, CPidMapper & pids ) const;
void MarkAsSpecial() { _fSpecial = TRUE; }
BOOL IsSpecial() { return _fSpecial; }
inline void SetPartialDeferred( BOOL fPartialDeferred ) { _fPartialDeferred = fPartialDeferred; }
PROPID PropId; // Property ID
private:
USHORT _obValue; // offset in row data (for key if compressed)
USHORT _cbValue; // width in row data (0 if compressed and no
// key needed
USHORT _obStatus; // offset in row data for value status (from
// DBSTATUSENUM, but stored in 1 byte)
USHORT _obLength; // offset in row data for value length (4 bytes)
USHORT _usStoreParts; // from StoreParts enum
VARTYPE _StoreAsType; // type stored in table
VARTYPE _PredominantType; BOOL _fUniformType; // TRUE if all data are of type
// _PredominantType
BOOL _fGlobalCompr; // TRUE if _pCompression is a global compression
BOOL _fSpecial; // TRUE if this property has special fetch/storage requirements
CCompressedCol * _pCompression; // pointer to compressed col. data
PROPID _CompressMasterID; // if !0, shared compression
BOOL _fPartialDeferred; // TRUE if the column is partial deferred
// (deferred till requested by client)
BOOL _IsSpecialPathProcessing( CTableColumn const & dstCol ) const; BOOL _GetPathOrFile( CTableColumn const & dstCol, const BYTE * pbSrc, PVarAllocator & rDstPool, BYTE * pbDstRow );
};
//+-------------------------------------------------------------------------
//
// Classes: CColumnMasterArray
// CTableColumnArray
//
// Purpose: Dynamic arrays of the classes above. These support
// Add, Get and Size methods. The CColumnMasterArray
// and CTableColumnArray are wrapped by set classes
// which add Find and other methods.
//
// Notes: In-place dynamic arrays can only be used with types
// which do not have destructors.
//
// Interface:
//
//--------------------------------------------------------------------------
DECL_DYNARRAY( CColumnMasterArray, CColumnMasterDesc ) DECL_DYNARRAY( CTableColumnArray, CTableColumn )
//+-------------------------------------------------------------------------
//
// Class: CTableColumnSet
//
// Purpose: A set of table columns. A dynamic array of columns
// with the addition of a Find method to lookup by PropID.
//
// Interface:
//
//--------------------------------------------------------------------------
class CTableColumnSet: public CTableColumnArray { public: CTableColumnSet(int size = 0) : _cColumns(0), CTableColumnArray( size) {}
CTableColumnSet( PDeSerStream & stm, CPidMapper & pids );
unsigned Count(void) const { return _cColumns; }
void SetCount(unsigned cCol) { _cColumns = cCol; }
void Add(CTableColumn* pCol, unsigned iCol);
void Add(XPtr<CTableColumn> & pCol, unsigned iCol);
CTableColumn* Find(PROPID const propid, BOOL& rfFound) const;
CTableColumn* Find(PROPID const propid) const;
void Marshall( PSerStream & stm, CPidMapper & pids ) const;
private: unsigned _cColumns; };
inline CTableColumn * CTableColumnSet::Find( PROPID const PropId ) const { for (unsigned i=0; i<Count(); i++) { CTableColumn* pCol = GetItem( i ); Win4Assert( 0 != pCol ); if ( pCol->PropId == PropId ) return pCol; } Win4Assert( !"propid not found" );
return 0; }
//+-------------------------------------------------------------------------
//
// Class: CColumnMasterSet
//
// Purpose: A set of master columns. Multiple instances of a
// column with the same property ID are collapsed in
// the set.
//
// Interface:
//
//--------------------------------------------------------------------------
class CColumnMasterSet { public: CColumnMasterSet(const CColumnSet* const pOutCols); CColumnMasterSet(unsigned Size);
//
// Add an instance of a column description
//
CColumnMasterDesc* Add(XPtr<CColumnMasterDesc> & xpNewItem);
CColumnMasterDesc* Add(CColumnMasterDesc const & rNewItem);
//
// Lookup a column by property ID. Returns NULL if not found.
//
CColumnMasterDesc* Find(const PROPID propid);
//
// Passthrough to CColumnMasterArray
//
inline unsigned Size(void) { return _iNextFree; } inline CColumnMasterDesc& Get(unsigned i) { return *_aMasterCol.Get(i); }
inline BOOL HasUserProp() { return _fHasUserProp; }
private: //
// Lookup a column by property ID. Returns NULL if not found.
//
CColumnMasterDesc* Find(const PROPID propid, unsigned& riCol);
unsigned _iNextFree; // index of next column to use
CColumnMasterArray _aMasterCol; // The column descriptors
BOOL _fHasUserProp; // TRUE if non-system (deferred) property in list
};
|