summaryrefslogtreecommitdiff
path: root/gcsdk/sqlaccess/schemafull.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gcsdk/sqlaccess/schemafull.cpp')
-rw-r--r--gcsdk/sqlaccess/schemafull.cpp409
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