diff options
Diffstat (limited to 'gcsdk/sqlaccess/schemafull.cpp')
| -rw-r--r-- | gcsdk/sqlaccess/schemafull.cpp | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/gcsdk/sqlaccess/schemafull.cpp b/gcsdk/sqlaccess/schemafull.cpp new file mode 100644 index 0000000..d8e9490 --- /dev/null +++ b/gcsdk/sqlaccess/schemafull.cpp @@ -0,0 +1,409 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//============================================================================= + + +#include "stdafx.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +namespace GCSDK +{ +CSchemaFull g_SchemaFull; +CSchemaFull & GSchemaFull() +{ + return g_SchemaFull; +} + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CSchemaFull::CSchemaFull() +{ + m_pubScratchBuffer = NULL; + m_cubScratchBuffer = 0; + m_unCheckSum = 0; + + m_mapFTSEnabled.SetLessFunc( DefLessFunc( enum ESchemaCatalog ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Destructor +//----------------------------------------------------------------------------- +CSchemaFull::~CSchemaFull() +{ + Uninit(); +} + + + +//----------------------------------------------------------------------------- +// Purpose: Call this after you've finished setting up the SchemaFull (either +// by loading it or by in GenerateIntrinsic). It calculates our checksum +// and allocates our scratch buffer. +//----------------------------------------------------------------------------- +void CSchemaFull::FinishInit() +{ + // Calculate our checksum + m_unCheckSum = 0; + + for ( int iSchema = 0; iSchema < m_VecSchema.Count(); iSchema++ ) + m_unCheckSum += m_VecSchema[iSchema].CalcChecksum(); + + // Allocate our scratch buffer + Assert( NULL == m_pubScratchBuffer ); + // Include some slop for field IDs and sizes in a sparse record + // 2k is way overkill but still no big deal + m_cubScratchBuffer = k_cubRecordMax + 2048; + m_pubScratchBuffer = ( uint8 * ) malloc( m_cubScratchBuffer ); +} + +//----------------------------------------------------------------------------- +// Purpose: Call this after you've finished setting up the SchemaFull (either +// by loading it or by in GenerateIntrinsic). It calculates our checksum +// and allocates our scratch buffer. +//----------------------------------------------------------------------------- + +void CSchemaFull::SetITable( CSchema* pSchema, int iTable ) +{ + // make sure we don't have this schema anywhere already + for ( int iSchema = 0; iSchema < m_VecSchema.Count(); iSchema++ ) + { + if ( pSchema != &m_VecSchema[iSchema] ) + AssertFatalMsg( m_VecSchema[iSchema].GetITable() != iTable, "Duplicate iTable in schema definition.\n" ); + } + + // set the pSchema object + pSchema->SetITable( iTable ); +} + + + +//----------------------------------------------------------------------------- +// Purpose: Uninits the schema. Need to call this explicitly before app shutdown +// on static instances of this object, as the CSchema objects +// point to memory in static memory pools which may destruct +// before static instances of this object. +//----------------------------------------------------------------------------- +void CSchemaFull::Uninit() +{ + m_VecSchema.RemoveAll(); + if ( NULL != m_pubScratchBuffer ) + { + free( m_pubScratchBuffer ); + m_pubScratchBuffer = NULL; + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Get the scratch buffer. It is large enough to handle any +// record, sparse or otherwise +// +//----------------------------------------------------------------------------- +uint8* CSchemaFull::GetPubScratchBuffer( ) +{ + return m_pubScratchBuffer; +} + + +//----------------------------------------------------------------------------- +// Purpose: This is used during the generation of our intrinsic schema. We've +// added a new schema to ourselves, and we need to make sure that it +// matches the corresponding C class. +// Input: pSchema - Schema to check +// cField - Number of fields the schema should contain. +// cubRecord - Size of a record in the schema +//----------------------------------------------------------------------------- +void CSchemaFull::CheckSchema( CSchema *pSchema, int cField, uint32 cubRecord ) +{ + // We generate our structures and our schema using macros that operate on the + // same source. We check a couple of things to make sure that they're properly in sync. + + // This will fail if the schema's definition specifies the wrong iTable + if ( pSchema != &m_VecSchema[pSchema->GetITable()] ) + { + EmitError( SPEW_SQL, "Table %s has a bad iTable\n", pSchema->GetPchName() ); + } + + // This will fail if there are missing lines in the schema definition + if ( pSchema->GetCField() != cField ) + { + EmitError( SPEW_SQL, "Badly formed table %s (blank line in schema def?)\n", pSchema->GetPchName() ); + AssertFatal( false ); + } + + // This is unlikely to fail. It indicates some kind of size mismatch (maybe a packing problem?) + if ( pSchema->CubRecordFixed() != cubRecord ) + { + // You may hit this if END_FIELDDATA_HAS_VAR_FIELDS is not used properly + EmitError( SPEW_SQL, "Table %s has an inconsistent size (class = %d, schema = %d)\n", + pSchema->GetPchName(), cubRecord, pSchema->CubRecordFixed() ); + AssertFatal( false ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Finds the table with a given name. +// Input: pchName - Name of the table to search for +// Output: Index of the matching table ( k_iTableNil if there isn't one) +//----------------------------------------------------------------------------- +int CSchemaFull::FindITable( const char *pchName ) +{ + for ( int iSchema = 0; iSchema < m_VecSchema.Count(); iSchema++ ) + { + if ( 0 == Q_strcmp( pchName, m_VecSchema[iSchema].GetPchName() ) ) + return iSchema; + } + + return k_iTableNil; +} + + +//----------------------------------------------------------------------------- +// Purpose: Finds the table with a given iTable (iSchema) +// Input: iTable - +// Output: NULL or a const char * to the name (for temporary use only) +//----------------------------------------------------------------------------- +const char * CSchemaFull::PchTableFromITable( int iTable ) +{ + if ( iTable < 0 || iTable >= m_VecSchema.Count() ) + return NULL; + else + return m_VecSchema[ iTable ].GetPchName(); +} + + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CSchemaFull::AddFullTextCatalog( enum ESchemaCatalog eCatalog, const char *pstrCatalogName, int nFileGroup ) +{ + CFTSCatalogInfo info; + info.m_eCatalog = eCatalog; + info.m_nFileGroup = nFileGroup; + info.m_pstrName = strdup(pstrCatalogName); + + m_vecFTSCatalogs.AddToTail( info ); +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +int CSchemaFull::GetFTSCatalogByName( enum ESchemaCatalog eCatalog, const char *pstrCatalogName ) +{ + int nIndex = -1; + FOR_EACH_VEC( m_vecFTSCatalogs, i ) + { + CFTSCatalogInfo &refInfo = m_vecFTSCatalogs[ i ]; + if ( 0 == Q_stricmp( pstrCatalogName, refInfo.m_pstrName ) ) + { + nIndex = i; + break; + } + } + + return nIndex; +} + + +//----------------------------------------------------------------------------- +// Purpose: turn on FTS for the named schema catalog. Called by the +// InitIntrinsic() function. +//----------------------------------------------------------------------------- +void CSchemaFull::EnableFTS( enum ESchemaCatalog eCatalog ) +{ + // mark it enabled in the map + m_mapFTSEnabled.Insert( eCatalog, true ); +} + + +//----------------------------------------------------------------------------- +// Purpose: is FTS enabled for the supplied schema catalog? +//----------------------------------------------------------------------------- +bool CSchemaFull::GetFTSEnabled( enum ESchemaCatalog eCatalog ) +{ + int iEntry = m_mapFTSEnabled.Find( eCatalog ); + if ( iEntry == m_mapFTSEnabled.InvalidIndex() ) + return false; + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Adds a schema conversion instruction (for use in converting from +// a different SchemaFull to this one). +//----------------------------------------------------------------------------- +void CSchemaFull::AddDeleteTable( const char *pchTableName ) +{ + DeleteTable_t &deleteTable = m_VecDeleteTable[m_VecDeleteTable.AddToTail()]; + Q_strncpy( deleteTable.m_rgchTableName, pchTableName, sizeof( deleteTable.m_rgchTableName ) ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Adds a schema conversion instruction (for use in converting from +// a different SchemaFull to this one). +//----------------------------------------------------------------------------- +void CSchemaFull::AddRenameTable( const char *pchTableNameOld, const char *pchTableNameNew ) +{ + RenameTable_t &renameTable = m_VecRenameTable[m_VecRenameTable.AddToTail()]; + Q_strncpy( renameTable.m_rgchTableNameOld, pchTableNameOld, sizeof( renameTable.m_rgchTableNameOld ) ); + renameTable.m_iTableDst = FindITable( pchTableNameNew ); + Assert( k_iTableNil != renameTable.m_iTableDst ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Adds a schema conversion instruction (for use in converting from +// a different SchemaFull to this one). +//----------------------------------------------------------------------------- +void CSchemaFull::AddDeleteField( const char *pchTableName, const char *pchFieldName ) +{ + int iSchema = FindITable( pchTableName ); + AssertFatal( k_iTableNil != iSchema ); + + m_VecSchema[iSchema].AddDeleteField( pchFieldName ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Adds a schema conversion instruction (for use in converting from +// a different SchemaFull to this one). +//----------------------------------------------------------------------------- +void CSchemaFull::AddRenameField( const char *pchTableName, const char *pchFieldNameOld, const char *pchFieldNameNew ) +{ + int iSchema = FindITable( pchTableName ); + AssertFatal( k_iTableNil != iSchema ); + + m_VecSchema[iSchema].AddRenameField( pchFieldNameOld, pchFieldNameNew ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Adds a schema conversion instruction (for use in converting from +// a different SchemaFull to this one). +//----------------------------------------------------------------------------- +void CSchemaFull::AddAlterField( const char *pchTableName, const char *pchFieldNameOld, const char *pchFieldnameNew, PfnAlterField_t pfnAlterField ) +{ + int iSchema = FindITable( pchTableName ); + AssertFatal( k_iTableNil != iSchema ); + + m_VecSchema[iSchema].AddAlterField( pchFieldNameOld, pchFieldnameNew, pfnAlterField ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Add a trigger to the desired schema +//----------------------------------------------------------------------------- +void CSchemaFull::AddTrigger( ESchemaCatalog eCatalog, const char *pchTableName, const char *pchTriggerName, ETriggerType eTriggerType, const char *pchTriggerText ) +{ + CTriggerInfo trigger; + trigger.m_eTriggerType = eTriggerType; + trigger.m_eSchemaCatalog = eCatalog; + Q_strncpy( trigger.m_szTriggerName, pchTriggerName, Q_ARRAYSIZE( trigger.m_szTriggerName ) ); + Q_strncpy( trigger.m_szTriggerTableName, pchTableName, Q_ARRAYSIZE( trigger.m_szTriggerTableName ) ); + trigger.m_strText = pchTriggerText; + + // add it to our list + m_VecTriggers.AddToTail( trigger ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Figures out how to map a table from another SchemaFull into us. +// First we check our conversion instructions to see if any apply, +// and then we look for a straightforward match. +// Input: pchTableName - Name of the table we're trying to map +// piTableDst - [Return] Index of the table to map it to +// Output: true if we know what to do with this table (if false, the conversion +// is undefined and dangerous). +//----------------------------------------------------------------------------- +bool CSchemaFull::BCanConvertTable( const char *pchTableName, int *piTableDst ) +{ + // Should this table be deleted? + for ( int iDeleteTable = 0; iDeleteTable < m_VecDeleteTable.Count(); iDeleteTable++ ) + { + if ( 0 == Q_strcmp( pchTableName, m_VecDeleteTable[iDeleteTable].m_rgchTableName ) ) + { + *piTableDst = k_iTableNil; + return true; + } + } + + // Should this table be renamed? + for ( int iRenameTable = 0; iRenameTable < m_VecRenameTable.Count(); iRenameTable++ ) + { + if ( 0 == Q_strcmp( pchTableName, m_VecRenameTable[iRenameTable].m_rgchTableNameOld ) ) + { + *piTableDst = m_VecRenameTable[iRenameTable].m_iTableDst; + return true; + } + } + + // Find out which of our tables this table maps to (if it doesn't map + // to any of them, we don't know what to do with it). + *piTableDst = FindITable( pchTableName ); + return ( k_iTableNil != *piTableDst ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Gets the default SQL schema name for a catalog +//----------------------------------------------------------------------------- +const char *CSchemaFull::GetDefaultSchemaNameForCatalog( ESchemaCatalog eCatalog ) +{ + // For all catalogs it's actually the same + if ( m_strDefaultSchemaName.IsEmpty() ) + { + m_strDefaultSchemaName.Set( CFmtStr( "App%u", GGCBase()->GetAppID() ) ); + } + + return m_strDefaultSchemaName.Get(); +} + + +#ifdef DBGFLAG_VALIDATE +//----------------------------------------------------------------------------- +// Purpose: Run a global validation pass on all of our data structures and memory +// allocations. +// Input: validator - Our global validator object +// pchName - Our name (typically a member var in our container) +//----------------------------------------------------------------------------- +void CSchemaFull::Validate( CValidator &validator, const char *pchName ) +{ + VALIDATE_SCOPE(); + + ValidateObj( m_VecSchema ); + for ( int iSchema = 0; iSchema < m_VecSchema.Count(); iSchema++ ) + { + ValidateObj( m_VecSchema[iSchema] ); + } + + ValidateObj( m_VecDeleteTable ); + ValidateObj( m_VecRenameTable ); + + ValidateObj( m_mapFTSEnabled ); + + ValidateObj( m_vecFTSCatalogs ); + FOR_EACH_VEC( m_vecFTSCatalogs, i ) + { + ValidateObj( m_vecFTSCatalogs[i] ); + } + + ValidateObj( m_VecTriggers ); + FOR_EACH_VEC( m_VecTriggers, i ) + { + ValidateObj( m_VecTriggers[i] ); + } + + validator.ClaimMemory( m_pubScratchBuffer ); +} +#endif // DBGFLAG_VALIDATE + +} // namespace GCSDK |