//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //============================================================================= #ifndef GCRECORDINFO_H #define GCRECORDINFO_H namespace GCSDK { typedef CUtlMap CMapIColumnInfo; // -------------------------------------------------------------------------- // Information about a column in a record (table or result set) class CColumnInfo { public: CColumnInfo(); ~CColumnInfo() { } void Set( const char *pchName, int nSQLColumn, EGCSQLType eGCSQLType, int cubFixedSize, int nColFlags, int cubMaxSize ); const char *GetName() const { return m_rgchName; } int GetSQLColumn() const { return m_nSQLColumn; } EGCSQLType GetType() const { return m_eType; } int GetFixedSize() const { return m_cubFixedSize; } int GetMaxSize() const { return m_cchMaxSize; } int GetChecksum() const { Assert( m_bHaveChecksum ); return m_nChecksum; } bool BIsVariableLength() const; int GetColFlags() const { return m_nColFlags; } void GetColFlagDescription( char* pstrOut, int cubOutLength ) const; int GetConstraintColFlags() { return m_nColFlags & k_nColFlagAllConstraints; } void SetColFlagBits( int nColFlag ); bool BIsIndexed() const { return 0 != ( m_nColFlags & k_nColFlagIndexed ); } bool BIsClustered() const { return 0 != ( m_nColFlags & k_nColFlagClustered ); } bool BIsUnique() const { return 0 != ( m_nColFlags & k_nColFlagUnique ); } bool BIsAutoIncrement() const { return 0 != ( m_nColFlags & k_nColFlagAutoIncrement ); } bool BIsPrimaryKey() const { return 0 != ( m_nColFlags & k_nColFlagPrimaryKey ); } bool BIsExplicitlyIndexed() const { return BIsIndexed() && !( BIsPrimaryKey() || BIsUnique() ); } bool BIsExplicitlyUnique() const { return BIsUnique() && !BIsPrimaryKey(); } bool BIsInsertable() const { return !BIsAutoIncrement(); } void CalculateChecksum(); void ValidateColFlags() const; bool operator==( const CColumnInfo& refOther ) const; bool operator!=( const CColumnInfo& refOther ) const { return ! operator==( refOther ); } #ifdef DBGFLAG_VALIDATE void Validate( CValidator &validator, const char *pchName ); #endif // DBGFLAG_VALIDATE private: CColumnInfo( CColumnInfo& ); // no copy constructor, disable default copy constructor CColumnInfo& operator = ( CColumnInfo& ); // no assignment operator, disable default assignment operator char m_rgchName[k_cSQLObjectNameMax+1]; EGCSQLType m_eType; // GC-based enum data type of this column int m_nColFlags; // flags for this column int m_nSQLColumn; // column # in SQL database to bind to, starts at 1. int m_cubFixedSize; // if fixed size, the fixed size in bytes; else 0 int m_cchMaxSize; // if variable size, the maximum size; else 0 int m_nChecksum; // checksum of this column info for quick comparisons bool m_bHaveChecksum; // have we calculated a checksum yet? }; // -------------------------------------------------------------------------- // Information about a record (table or result set) class CRecordInfo : public CRefCount { public: CRecordInfo(); void InitFromDSSchema( CSchema *pSchema ); void SetName( const char *pchName ); const char *GetName() const { return m_rgchName; } void AddColumn( const char *pchName, int nSQLColumn, EGCSQLType eGCSQLType, int cubFixedSize, int nColFlags, int cubMaxSize ); void SetAllColumnsAdded() { m_bAllColumnsAdded = true; } void PrepareForUse(); int GetFixedSize() const { return m_cubFixedSize; } int GetNumColumns() const { return m_VecColumnInfo.Count(); } const CColumnInfo &GetColumnInfo( uint32 unColumn ) const { return m_VecColumnInfo[unColumn]; } CColumnInfo &GetColumnInfo( uint32 unColumn ) { return m_VecColumnInfo[unColumn]; } bool BFindColumnByName( const char *pchName, int *piColumn ); bool BPreparedForUse() const { return m_bPreparedForUse; } void EnsureCapacity( int cColumns ) { m_VecColumnInfo.EnsureCapacity( cColumns ); } int GetChecksum(); ESchemaCatalog GetESchemaCatalog() const { return m_eSchemaCatalog; } void SetESchemaCatalog( ESchemaCatalog e ) { m_eSchemaCatalog = e; } bool EqualTo( CRecordInfo* pOther ); bool CompareIndexLists( CRecordInfo *pOther ); bool CompareFKs( CRecordInfo *pOther ); bool CompareFTSIndexLists( CRecordInfo *pOther ) const; EPrimaryKeyType GetPrimaryKeyType() const { return m_nHasPrimaryKey; } bool BHasPrimaryKey() { return GetPrimaryKeyType() != k_EPrimaryKeyTypeNone; } const FieldSet_t& GetPKFields() { Assert( BHasPrimaryKey()); return GetIndexFields( )[ m_iPKIndex ]; } const CUtlVector& GetIndexFields() const { return m_VecIndexes; } int GetIndexFieldCount() const { return m_VecIndexes.Count(); } int FindIndex( CRecordInfo *pRec, const FieldSet_t& fieldSet ); int FindIndexByName( const char *pszName ) const; int GetPKIndex() const { return m_iPKIndex; } void SetPKIndex( int i ) { m_iPKIndex = i; } int AddIndex( const FieldSet_t& fieldSet ); void GetIndexFieldList( CFmtStr1024 *pstr, int nIndents ) const; int GetTableID() const { return m_nTableID; } void SetTableID( int nTableID ) { m_nTableID = nTableID; } bool BHasIdentity() const; // full-text index CUtlVector & GetFTSFields() { return m_vecFTSFields; } bool BHasFTSIndex() const { return m_vecFTSFields.Count() > 0; } void AddFTSFields( CUtlVector< int > &refVecFields ); int GetFullTextCatalogIndex() { return m_nFullTextCatalogIndex; } // foreign keys void AddFK( const FKData_t &fkData ); void GetFKListString( CFmtStr1024 *pstr, int nIndents ); int GetFKCount(); FKData_t &GetFKData( int iIndex ); static CRecordInfo *Alloc(); #ifdef DBGFLAG_VALIDATE static void ValidateStatics( CValidator &validator, const char *pchName ); void Validate( CValidator &validator, const char *pchName ); #endif //DBGFLAG_VALIDATE // note: destructor is private. This is a ref-counted object, private destructor ensures callers can't accidentally delete // directly, or declare on stack virtual ~CRecordInfo() { } private: virtual void DestroyThis(); void CalculateChecksum(); void BuildColumnNameIndex(); char m_rgchName[k_cSQLObjectNameMax+1]; int m_nTableID; // Object_ID if this table in SQL Server CUtlVector m_VecColumnInfo; // Vector of columns in this record CMapIColumnInfo m_MapIColumnInfo; // Map of name->column index for quick lookup by name EPrimaryKeyType m_nHasPrimaryKey; // Does this table contain a column that is a primary key? int m_iPKIndex; // index info m_VecIndexes of our PK index; -1 if no PK CUtlVector m_VecIndexes; // vector of all fields in all indexes int m_cubFixedSize; // Sum of data sizes for all fixed size columns bool m_bAllColumnsAdded; // Have all columns been added bool m_bPreparedForUse; // Have we finished being initialized? bool m_bHaveColumnNameIndex; // Have we created a column name index? (Only generated if someone asks.) bool m_bHaveChecksum; // Have we generated a checksum? (Only generated if someone asks.) int m_nChecksum; // checksum of this record info for quick comparisons - includes all columns ESchemaCatalog m_eSchemaCatalog; // what catalog owns this object? CUtlVector< int > m_vecFTSFields; // which fields have FTS indexing? int m_nFullTextCatalogIndex; // index of catalog for FTS index, if we get one CUtlVector m_VecFKData; // vector of all FK relationships defined on this table CThreadMutex m_Mutex; static CThreadSafeClassMemoryPool sm_MemPoolRecordInfo; #ifdef _DEBUG // validation tracking static CUtlRBTree sm_mapPMemPoolRecordInfo; static CThreadMutex sm_mutexMemPoolRecordInfo; #endif }; int __cdecl CompareColumnInfo( const CColumnInfo *pColumnInfoLeft, const CColumnInfo *pColumnInfoRight ); } // namespace GCSDK #endif // GCRECORDINFO_H