Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
9.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Sets of columns in queries
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #ifndef COLUMNSET_H
  8. #define COLUMNSET_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. namespace GCSDK
  13. {
  14. //-----------------------------------------------------------------------------
  15. // Purpose: Sets of columns in queries
  16. //-----------------------------------------------------------------------------
  17. class CColumnSet
  18. {
  19. public:
  20. CColumnSet( const CRecordInfo *pRecordInfo );
  21. CColumnSet( const CColumnSet & rhs );
  22. CColumnSet & operator=( const CColumnSet & rhs );
  23. const CColumnSet operator+( const CColumnSet & rhs ) const;
  24. CColumnSet & operator+=( const CColumnSet & rhs );
  25. //NOTE: These do not ensure uniqueness, the CSET_ macros below should be used instead as they will compile time enforce uniqueness
  26. CColumnSet( const CRecordInfo *pRecordInfo, int col1 );
  27. CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2 );
  28. CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3 );
  29. CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4 );
  30. CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4, int col5 );
  31. CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4, int col5, int col6 );
  32. CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4, int col5, int col6, int col7 );
  33. CColumnSet( const CRecordInfo *pRecordInfo, int col1, int col2, int col3, int col4, int col5, int col6, int col7, int col8 );
  34. void BAddColumn( int nColumn );
  35. void BRemoveColumn( int nColumn );
  36. bool IsSet( int nColumn ) const;
  37. bool IsEmpty() const { return m_vecColumns.Count() == 0;}
  38. uint32 GetColumnCount() const;
  39. int GetColumn( int nIndex ) const;
  40. const CColumnInfo & GetColumnInfo( int nIndex ) const;
  41. const CRecordInfo *GetRecordInfo() const { return m_pRecordInfo; }
  42. void MakeEmpty();
  43. void MakeFull();
  44. void MakeInsertable();
  45. void MakeNoninsertable();
  46. void MakePrimaryKey();
  47. void MakeInverse( const CColumnSet & columnSet );
  48. //determines if the current column set has all fields set. Useful for detection of new columns being added to the schema
  49. bool BAreAllFieldsSet() const;
  50. template< typename TSchClass >
  51. static CColumnSet Empty();
  52. template< typename TSchClass >
  53. static CColumnSet Full();
  54. template< typename TSchClass >
  55. static CColumnSet Insertable();
  56. template< typename TSchClass >
  57. static CColumnSet Noninsertable();
  58. template< typename TSchClass >
  59. static CColumnSet PrimaryKey();
  60. static CColumnSet Inverse( const CColumnSet & columnSet );
  61. #ifdef DBGFLAG_VALIDATE
  62. void Validate( CValidator &validator, const char *pchName );
  63. #endif
  64. private:
  65. CUtlVector<int> m_vecColumns;
  66. const CRecordInfo *m_pRecordInfo;
  67. };
  68. //this is a utility class which can at compile time ensure that all of the provided column values are unique and will generate an error if that doesn't
  69. //hold true. The default values just need to be unique and greater than what is expected for real columns
  70. template < int n1 = 10001, int n2 = 10002, int n3 = 10003, int n4 = 10004, int n5 = 10005, int n6 = 10006, int n7 = 10007, int n8 = 10008 >
  71. class CUniqueColChecker
  72. {
  73. public:
  74. //this is a simple pass through so that it can wrap the declaration of a column set
  75. static const CColumnSet& VerifyUnique( const CColumnSet& cs )
  76. {
  77. COMPILE_TIME_ASSERT( n1 != n2 && n1 != n3 && n1 != n4 && n1 != n5 && n1 != n6 && n1 != n7 && n1 != n8 );
  78. COMPILE_TIME_ASSERT( n2 != n3 && n2 != n4 && n2 != n5 && n2 != n6 && n2 != n7 && n2 != n8 );
  79. COMPILE_TIME_ASSERT( n3 != n4 && n3 != n5 && n3 != n6 && n3 != n7 && n3 != n8 );
  80. COMPILE_TIME_ASSERT( n4 != n5 && n4 != n6 && n4 != n7 && n4 != n8 );
  81. COMPILE_TIME_ASSERT( n5 != n6 && n5 != n7 && n5 != n8 );
  82. COMPILE_TIME_ASSERT( n6 != n7 && n6 != n8 );
  83. COMPILE_TIME_ASSERT( n7 != n8 );
  84. return cs;
  85. }
  86. };
  87. // Usage notes:
  88. // The fields in a column set are order-dependent, and must match the order of the fields in
  89. // the query used to generate the data. The code that reads values doesn't do any fancy
  90. // name-matching and will copy values to incorrect locations silently if there is a
  91. // disagreement between the fields in the query and the fields in the column set.
  92. //
  93. // Examples:
  94. // // This is broken.
  95. // query = "SELECT * FROM Items";
  96. // columnSet = CSET_12_COL( CSchItem, individual_field_names );
  97. //
  98. // // This is fixed.
  99. // query = "SELECT * FROM Items";
  100. // columnSet = CSET_FULL( ... );
  101. #define FOR_EACH_COLUMN_IN_SET( columnSet, iterName ) for( uint32 iterName = 0; iterName < (columnSet).GetColumnCount(); iterName++ )
  102. #define CSET_EMPTY( schClass ) CColumnSet::Empty<schClass>()
  103. #define CSET_FULL( schClass ) CColumnSet::Full<schClass>()
  104. #define CSET_INSERTABLE( schClass ) CColumnSet::Insertable<schClass>()
  105. #define CSET_NONINSERTABLE( schClass ) CColumnSet::Noninsertable<schClass>()
  106. #define CSET_PK( schClass ) CColumnSet::PrimaryKey<schClass>()
  107. #define CSET_1_COL( schClass, col1 ) \
  108. CColumnSet( GSchemaFull().GetSchema( schClass::k_iTable ).GetRecordInfo(), schClass::col1 )
  109. #define CSET_2_COL( schClass, col1, col2 ) \
  110. CUniqueColChecker< schClass::col1, schClass::col2 >::VerifyUnique( \
  111. CColumnSet( GSchemaFull().GetSchema( schClass::k_iTable ).GetRecordInfo(), schClass::col1, schClass::col2 ) )
  112. #define CSET_3_COL( schClass, col1, col2, col3 ) \
  113. CUniqueColChecker< schClass::col1, schClass::col2, schClass::col3 >::VerifyUnique( \
  114. CColumnSet( GSchemaFull().GetSchema( schClass::k_iTable ).GetRecordInfo(), schClass::col1, schClass::col2, schClass::col3 ) )
  115. #define CSET_4_COL( schClass, col1, col2, col3, col4 ) \
  116. CUniqueColChecker< schClass::col1, schClass::col2, schClass::col3, schClass::col4 >::VerifyUnique( \
  117. CColumnSet( GSchemaFull().GetSchema( schClass::k_iTable ).GetRecordInfo(), schClass::col1, schClass::col2, schClass::col3, schClass::col4 ) )
  118. #define CSET_5_COL( schClass, col1, col2, col3, col4, col5 ) \
  119. CUniqueColChecker< schClass::col1, schClass::col2, schClass::col3, schClass::col4, schClass::col5 >::VerifyUnique( \
  120. CColumnSet( GSchemaFull().GetSchema( schClass::k_iTable ).GetRecordInfo(), schClass::col1, schClass::col2, schClass::col3, schClass::col4, schClass::col5 ) )
  121. #define CSET_6_COL( schClass, col1, col2, col3, col4, col5, col6 ) \
  122. CUniqueColChecker< schClass::col1, schClass::col2, schClass::col3, schClass::col4, schClass::col5, schClass::col6 >::VerifyUnique( \
  123. CColumnSet( GSchemaFull().GetSchema( schClass::k_iTable ).GetRecordInfo(), schClass::col1, schClass::col2, schClass::col3, schClass::col4, schClass::col5, schClass::col6 ) )
  124. #define CSET_7_COL( schClass, col1, col2, col3, col4, col5, col6, col7 ) \
  125. CUniqueColChecker< schClass::col1, schClass::col2, schClass::col3, schClass::col4, schClass::col5, schClass::col6, schClass::col7 >::VerifyUnique( \
  126. CColumnSet( GSchemaFull().GetSchema( schClass::k_iTable ).GetRecordInfo(), schClass::col1, schClass::col2, schClass::col3, schClass::col4, schClass::col5, schClass::col6, schClass::col7 ) )
  127. #define CSET_8_COL( schClass, col1, col2, col3, col4, col5, col6, col7, col8 ) \
  128. CUniqueColChecker< schClass::col1, schClass::col2, schClass::col3, schClass::col4, schClass::col5, schClass::col6, schClass::col7, schClass::col8 >::VerifyUnique( \
  129. CColumnSet( GSchemaFull().GetSchema( schClass::k_iTable ).GetRecordInfo(), schClass::col1, schClass::col2, schClass::col3, schClass::col4, schClass::col5, schClass::col6, schClass::col7, schClass::col8 ) )
  130. //-----------------------------------------------------------------------------
  131. // Purpose: Returns an empty Column Set for a schema class
  132. //-----------------------------------------------------------------------------
  133. template< typename TSchClass >
  134. CColumnSet CColumnSet::Empty()
  135. {
  136. CColumnSet set( GSchemaFull().GetSchema( TSchClass::k_iTable ).GetRecordInfo() );
  137. return set;
  138. }
  139. //-----------------------------------------------------------------------------
  140. // Purpose: Returns a Column Set for a schema class which contains every field
  141. //-----------------------------------------------------------------------------
  142. template< typename TSchClass >
  143. CColumnSet CColumnSet::Full()
  144. {
  145. CColumnSet set( GSchemaFull().GetSchema( TSchClass::k_iTable ).GetRecordInfo() );
  146. set.MakeFull();
  147. return set;
  148. }
  149. //-----------------------------------------------------------------------------
  150. // Purpose: Returns a Column Set for a schema class which contains every
  151. // insertable field
  152. //-----------------------------------------------------------------------------
  153. template< typename TSchClass >
  154. CColumnSet CColumnSet::Insertable()
  155. {
  156. CColumnSet set( GSchemaFull().GetSchema( TSchClass::k_iTable ).GetRecordInfo() );
  157. set.MakeInsertable();
  158. return set;
  159. }
  160. //-----------------------------------------------------------------------------
  161. // Purpose: Returns a Column Set for a schema class which contains every
  162. // noninsertable field
  163. //-----------------------------------------------------------------------------
  164. template< typename TSchClass >
  165. CColumnSet CColumnSet::Noninsertable()
  166. {
  167. CColumnSet set( GSchemaFull().GetSchema( TSchClass::k_iTable ).GetRecordInfo() );
  168. set.MakeNoninsertable();
  169. return set;
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Purpose: Returns a Column Set for a schema class which contains every
  173. // primary key field
  174. //-----------------------------------------------------------------------------
  175. template< typename TSchClass >
  176. CColumnSet CColumnSet::PrimaryKey()
  177. {
  178. CColumnSet set( GSchemaFull().GetSchema( TSchClass::k_iTable ).GetRecordInfo() );
  179. set.MakePrimaryKey();
  180. return set;
  181. }
  182. } // namespace GCSDK
  183. #endif // COLUMNSET_H