//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: Sets of columns in SQL queries // // $NoKeywords: $ //============================================================================= #include "stdafx.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" namespace GCSDK { //----------------------------------------------------------------------------- // Purpose: Constructs a column set with no columns in it //----------------------------------------------------------------------------- CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo ) : m_pRecordInfo( pRecordInfo ) { } //----------------------------------------------------------------------------- // Purpose: Constructs a column set with a single column in it // Inputs: nColumn - the column to add //----------------------------------------------------------------------------- CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo, int col1 ) : m_pRecordInfo( pRecordInfo ) { m_vecColumns.AddToTail( col1 ); } CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2 ) : m_pRecordInfo( pRecordInfo ) { m_vecColumns.EnsureCapacity( 2 ); m_vecColumns.AddToTail( col1 ); m_vecColumns.AddToTail( col2 ); } CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3 ) : m_pRecordInfo( pRecordInfo ) { m_vecColumns.EnsureCapacity( 3 ); m_vecColumns.AddToTail( col1 ); m_vecColumns.AddToTail( col2 ); m_vecColumns.AddToTail( col3 ); } CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4 ) : m_pRecordInfo( pRecordInfo ) { m_vecColumns.EnsureCapacity( 4 ); m_vecColumns.AddToTail( col1 ); m_vecColumns.AddToTail( col2 ); m_vecColumns.AddToTail( col3 ); m_vecColumns.AddToTail( col4 ); } CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4, int col5 ) : m_pRecordInfo( pRecordInfo ) { m_vecColumns.EnsureCapacity( 5 ); m_vecColumns.AddToTail( col1 ); m_vecColumns.AddToTail( col2 ); m_vecColumns.AddToTail( col3 ); m_vecColumns.AddToTail( col4 ); m_vecColumns.AddToTail( col5 ); } CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4, int col5, int col6 ) : m_pRecordInfo( pRecordInfo ) { m_vecColumns.EnsureCapacity( 6 ); m_vecColumns.AddToTail( col1 ); m_vecColumns.AddToTail( col2 ); m_vecColumns.AddToTail( col3 ); m_vecColumns.AddToTail( col4 ); m_vecColumns.AddToTail( col5 ); m_vecColumns.AddToTail( col6 ); } CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4, int col5, int col6, int col7 ) : m_pRecordInfo( pRecordInfo ) { m_vecColumns.EnsureCapacity( 7 ); m_vecColumns.AddToTail( col1 ); m_vecColumns.AddToTail( col2 ); m_vecColumns.AddToTail( col3 ); m_vecColumns.AddToTail( col4 ); m_vecColumns.AddToTail( col5 ); m_vecColumns.AddToTail( col6 ); m_vecColumns.AddToTail( col7 ); } CColumnSet::CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4, int col5, int col6, int col7, int col8 ) : m_pRecordInfo( pRecordInfo ) { m_vecColumns.EnsureCapacity( 8 ); m_vecColumns.AddToTail( col1 ); m_vecColumns.AddToTail( col2 ); m_vecColumns.AddToTail( col3 ); m_vecColumns.AddToTail( col4 ); m_vecColumns.AddToTail( col5 ); m_vecColumns.AddToTail( col6 ); m_vecColumns.AddToTail( col7 ); m_vecColumns.AddToTail( col8 ); } //----------------------------------------------------------------------------- // Purpose: Copy constructor //----------------------------------------------------------------------------- CColumnSet::CColumnSet( const CColumnSet & rhs ) { MEM_ALLOC_CREDIT_("CColumnSet"); m_vecColumns.CopyArray( rhs.m_vecColumns.Base(), rhs.m_vecColumns.Count() ); m_pRecordInfo = rhs.m_pRecordInfo; } //----------------------------------------------------------------------------- // Purpose: Assignment operator //----------------------------------------------------------------------------- CColumnSet & CColumnSet::operator=( const CColumnSet & rhs ) { MEM_ALLOC_CREDIT_("CColumnSet"); m_vecColumns.CopyArray( rhs.m_vecColumns.Base(), rhs.m_vecColumns.Count() ); m_pRecordInfo = rhs.m_pRecordInfo; return *this; } //----------------------------------------------------------------------------- // Purpose: Addition operator. lhs ColumnSet will be a union of the two // ColumnSets //----------------------------------------------------------------------------- CColumnSet & CColumnSet::operator+=( const CColumnSet & rhs ) { Assert( this->GetRecordInfo() == rhs.GetRecordInfo() ); FOR_EACH_COLUMN_IN_SET( rhs, i ) { BAddColumn( rhs.GetColumn( i ) ); } return *this; } //----------------------------------------------------------------------------- // Purpose: Addition operator. Returns a union of lhs and rhs //----------------------------------------------------------------------------- const CColumnSet CColumnSet::operator+( const CColumnSet & rhs ) const { return CColumnSet( *this ) += rhs; } //----------------------------------------------------------------------------- // Purpose: Adds a column to the set if it is // Inputs: nColumn - THe column to add //----------------------------------------------------------------------------- void CColumnSet::BAddColumn( int nColumn ) { if( nColumn >= 0 && nColumn < m_pRecordInfo->GetNumColumns() ) { //not sure best way to handle the 'is already set case' if( !IsSet( nColumn ) ) m_vecColumns.AddToTail( nColumn ); } else { AssertMsg3( false, "Attempting to set an out of range column on schema type %s, %d (of %d)", GetRecordInfo()->GetName(), nColumn, m_pRecordInfo->GetNumColumns() ); } } //----------------------------------------------------------------------------- // Purpose: Removes a column from the set // Inputs: nColumn - THe column to remove //----------------------------------------------------------------------------- void CColumnSet::BRemoveColumn( int nColumn ) { m_vecColumns.FindAndRemove( nColumn ); } //----------------------------------------------------------------------------- // Purpose: Returns true if a column is in the set // Inputs: nColumn - THe column to test //----------------------------------------------------------------------------- bool CColumnSet::IsSet( int nColumn ) const { int nIndex = m_vecColumns.Find( nColumn ); return m_vecColumns.IsValidIndex( nIndex ); } //----------------------------------------------------------------------------- // Purpose: Returns the number of columns in the set //----------------------------------------------------------------------------- uint32 CColumnSet::GetColumnCount() const { return m_vecColumns.Count(); } //----------------------------------------------------------------------------- // Purpose: Returns the column index of the Nth column in the set // Inputs: nIndex - the position in the set to return a column index for. //----------------------------------------------------------------------------- int CColumnSet::GetColumn( int nIndex ) const { return m_vecColumns[nIndex]; } //----------------------------------------------------------------------------- // Purpose: Returns a CColumnInfo object for the nth column in the set // Inputs: nIndex - the position in the set to return a column info for. //----------------------------------------------------------------------------- const CColumnInfo & CColumnSet::GetColumnInfo( int nIndex ) const { return m_pRecordInfo->GetColumnInfo( GetColumn( nIndex ) ); } //----------------------------------------------------------------------------- // Purpose: Empties the column set //----------------------------------------------------------------------------- void CColumnSet::MakeEmpty() { m_vecColumns.RemoveAll(); } //----------------------------------------------------------------------------- // Purpose: Makes the column set be the full set of all columns in the record info //----------------------------------------------------------------------------- void CColumnSet::MakeFull() { MakeEmpty(); const int nNumColumns = m_pRecordInfo->GetNumColumns(); m_vecColumns.EnsureCapacity( nNumColumns ); for( int nColumn = 0; nColumn < m_pRecordInfo->GetNumColumns(); nColumn++ ) { //do a direct add to avoid the exponential cost since we know we won't have conflicts m_vecColumns.AddToTail( nColumn ); } } //----------------------------------------------------------------------------- // Purpose: Makes the column set be the full set of all insertable columns in // the record info //----------------------------------------------------------------------------- void CColumnSet::MakeInsertable() { MakeEmpty(); for( int nColumn = 0; nColumn < m_pRecordInfo->GetNumColumns(); nColumn++ ) { const CColumnInfo & columnInfo = m_pRecordInfo->GetColumnInfo( nColumn ); if( columnInfo.BIsInsertable() ) { //do a direct add to avoid the exponential cost since we know we won't have conflicts m_vecColumns.AddToTail( nColumn ); } } } //----------------------------------------------------------------------------- // Purpose: Makes the column set be the full set of all noninsertable columns in // the record info //----------------------------------------------------------------------------- void CColumnSet::MakeNoninsertable() { MakeEmpty(); for( int nColumn = 0; nColumn < m_pRecordInfo->GetNumColumns(); nColumn++ ) { const CColumnInfo & columnInfo = m_pRecordInfo->GetColumnInfo( nColumn ); if( !columnInfo.BIsInsertable() ) { //do a direct add to avoid the exponential cost since we know we won't have conflicts m_vecColumns.AddToTail( nColumn ); } } } //----------------------------------------------------------------------------- // Purpose: Makes the column set be the full set of all primary key columns in // the record info //----------------------------------------------------------------------------- void CColumnSet::MakePrimaryKey() { MakeEmpty(); for( int nColumn = 0; nColumn < m_pRecordInfo->GetNumColumns(); nColumn++ ) { const CColumnInfo & columnInfo = m_pRecordInfo->GetColumnInfo( nColumn ); if( columnInfo.BIsPrimaryKey() ) { //do a direct add to avoid the exponential cost since we know we won't have conflicts m_vecColumns.AddToTail( nColumn ); } } } //----------------------------------------------------------------------------- // Purpose: Makes the column set be the full set of all primary key columns in // the record info //----------------------------------------------------------------------------- void CColumnSet::MakeInverse( const CColumnSet & columnSet ) { MakeEmpty(); for( int nColumn = 0; nColumn < m_pRecordInfo->GetNumColumns(); nColumn++ ) { if( !columnSet.IsSet( nColumn ) ) { //do a direct add to avoid the exponential cost since we know we won't have conflicts m_vecColumns.AddToTail( nColumn ); } } } //----------------------------------------------------------------------------- // determines if the current column set has all fields set. Useful for detection of new columns being added to the schema //----------------------------------------------------------------------------- bool CColumnSet::BAreAllFieldsSet() const { for( int nColumn = 0; nColumn < m_pRecordInfo->GetNumColumns(); nColumn++ ) { if( !IsSet( nColumn ) ) return false; } return true; } //----------------------------------------------------------------------------- // Purpose: Returns a Column Set which is the inverse of the given column set // STATIC - Difference from MakeInverse is that it has a return value //----------------------------------------------------------------------------- CColumnSet CColumnSet::Inverse( const CColumnSet & columnSet ) { CColumnSet set( columnSet.GetRecordInfo() ); set.MakeInverse( columnSet ); return set; } //----------------------------------------------------------------------------- // Purpose: Claims the memory for CColumnSet //----------------------------------------------------------------------------- #ifdef DBGFLAG_VALIDATE void CColumnSet::Validate( CValidator &validator, const char *pchName ) { // these are INSIDE the function instead of outside so the interface // doesn't change VALIDATE_SCOPE(); ValidateObj( m_vecColumns ); } #endif } // namespace GCSDK