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.

538 lines
16 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "stdafx.h"
  8. //#include "sqlaccess.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. namespace GCSDK
  12. {
  13. //-----------------------------------------------------------------------------
  14. // Purpose: Constructor
  15. //-----------------------------------------------------------------------------
  16. CSQLRecord::CSQLRecord( uint32 unRow, IGCSQLResultSet *pResultSet )
  17. {
  18. Init( unRow, pResultSet );
  19. }
  20. CSQLRecord::CSQLRecord()
  21. : m_pResultSet( NULL ), m_unRow( 0 )
  22. {
  23. }
  24. //-----------------------------------------------------------------------------
  25. // Purpose: Destructor
  26. //-----------------------------------------------------------------------------
  27. CSQLRecord::~CSQLRecord()
  28. {
  29. }
  30. //-----------------------------------------------------------------------------
  31. // Purpose: Initializes a blank record
  32. // Input: iTable - table that this record will belong to
  33. //-----------------------------------------------------------------------------
  34. void CSQLRecord::Init( uint32 unRow, IGCSQLResultSet *pResultSet )
  35. {
  36. if( unRow >= pResultSet->GetRowCount() )
  37. {
  38. m_pResultSet = NULL;
  39. m_unRow = 0;
  40. }
  41. else
  42. {
  43. m_pResultSet = pResultSet;
  44. m_unRow = unRow;
  45. }
  46. }
  47. //-----------------------------------------------------------------------------
  48. // Purpose: Gets data for a field in this record
  49. // Input: unColumn - field to get
  50. // pubField - pointer to get filled in with pointer to data
  51. // cubField - pointer to get filled in with size of data
  52. // Output: true if successful, false if data not present
  53. //-----------------------------------------------------------------------------
  54. bool CSQLRecord::BGetColumnData( uint32 unColumn, uint8 **ppubField, int *pcubField )
  55. {
  56. size_t sz;
  57. bool bRet = BGetColumnData( unColumn, ppubField, &sz );
  58. *pcubField = static_cast< int >( sz );
  59. return bRet;
  60. }
  61. //-----------------------------------------------------------------------------
  62. // Purpose: Gets data for a field in this record
  63. // Input: unColumn - field to get
  64. // pubField - pointer to get filled in with pointer to data
  65. // cubField - pointer to get filled in with size of data
  66. // Output: true if successful, false if data not present
  67. //-----------------------------------------------------------------------------
  68. bool CSQLRecord::BGetColumnData( uint32 unColumn, uint8 **ppubField, size_t *pcubField )
  69. {
  70. Assert( ppubField );
  71. Assert( pcubField );
  72. *ppubField = NULL;
  73. *pcubField = 0;
  74. Assert( m_pResultSet );
  75. if ( !BValidateColumnIndex( unColumn ) )
  76. return false;
  77. *pcubField = 0;
  78. return m_pResultSet->GetData( m_unRow, unColumn, ppubField, (uint32*)pcubField );
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose: Gets string data for a field in this record
  82. // Input: unColumn - field to get
  83. // ppchVal - pointer to pointer to fill in to string data
  84. // Output: true if successful, false if data not present or not of correct type
  85. //-----------------------------------------------------------------------------
  86. bool CSQLRecord::BGetStringValue( uint32 unColumn, const char **ppchVal )
  87. {
  88. Assert( ppchVal );
  89. *ppchVal = NULL;
  90. uint8 *pubData = NULL;
  91. int cubData = 0;
  92. Assert( k_EGCSQLType_String == m_pResultSet->GetColumnType( unColumn ) );
  93. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  94. if ( bRet )
  95. *ppchVal = (const char *) pubData;
  96. return bRet;
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Purpose: Gets string data for a field in this record
  100. // Input: unColumn - field to get
  101. // ppchVal - pointer to pointer to fill in to string data
  102. // Output: true if successful, false if data not present or not of correct type
  103. //-----------------------------------------------------------------------------
  104. bool CSQLRecord::BGetStringValue( uint32 unColumn, CFmtStr1024 *psVal )
  105. {
  106. Assert( psVal );
  107. *psVal = "";
  108. uint8 *pubData = NULL;
  109. int cubData = 0;
  110. Assert( k_EGCSQLType_String == m_pResultSet->GetColumnType( unColumn ) );
  111. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  112. if ( bRet )
  113. *psVal = (const char *) pubData;
  114. return bRet;
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose: Gets int data for a field in this record
  118. // Input: unColumn - field to get
  119. // pnVal - pointer to fill in with data
  120. // Output: true if successful, false if data not present or not of correct type
  121. //-----------------------------------------------------------------------------
  122. bool CSQLRecord::BGetIntValue( uint32 unColumn, int *pnVal )
  123. {
  124. Assert( pnVal );
  125. *pnVal = 0;
  126. uint8 *pubData = NULL;
  127. int cubData = 0;
  128. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  129. if ( bRet )
  130. {
  131. switch( m_pResultSet->GetColumnType( unColumn ) )
  132. {
  133. case k_EGCSQLType_int64:
  134. {
  135. int64 ul = *((int64 *)pubData);
  136. if ( ul >= LONG_MIN && ul <= LONG_MAX )
  137. {
  138. *pnVal = (int)ul;
  139. return true;
  140. }
  141. else
  142. {
  143. AssertMsg1(false, "GetIntValue tried to catch %lld in an int, which is too small", ul );
  144. return false;
  145. }
  146. }
  147. break;
  148. case k_EGCSQLType_int32:
  149. *pnVal = *((int32 *)pubData);
  150. return true;
  151. case k_EGCSQLType_int16:
  152. *pnVal = *((int16 *)pubData);
  153. return true;
  154. case k_EGCSQLType_int8:
  155. *pnVal = *((int8 *)pubData);
  156. return true;
  157. default:
  158. AssertMsg1(false, "GetIntValue tried to catch a %s, which is the wrong type", PchNameFromEGCSQLType( m_pResultSet->GetColumnType( unColumn ) ) );
  159. return false;
  160. }
  161. }
  162. return bRet;
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Purpose: Gets float data for a field in this record
  166. // Input: unColumn - field to get
  167. // pnVal - pointer to fill in with data
  168. // Output: true if successful, false if data not present or not of correct type
  169. //-----------------------------------------------------------------------------
  170. bool CSQLRecord::BGetFloatValue( uint32 unColumn, float *pfVal )
  171. {
  172. Assert( pfVal );
  173. *pfVal = 0.0f;
  174. uint8 *pubData = NULL;
  175. int cubData = 0;
  176. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  177. if ( bRet )
  178. {
  179. Assert( k_EGCSQLType_float == m_pResultSet->GetColumnType( unColumn ) );
  180. AssertMsg2( sizeof( float ) == cubData, "GetValue expected %llu bytes, found %d", (uint64)sizeof( float ), cubData );
  181. if ( sizeof( float ) != cubData )
  182. return false;
  183. *pfVal = *( (float *) pubData );
  184. }
  185. return bRet;
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Purpose: Gets double data for a field in this record
  189. // Input: unColumn - field to get
  190. // pnVal - pointer to fill in with data
  191. // Output: true if successful, false if data not present or not of correct type
  192. //-----------------------------------------------------------------------------
  193. bool CSQLRecord::BGetDoubleValue( uint32 unColumn, double *pdVal )
  194. {
  195. Assert( pdVal );
  196. *pdVal = 0.0f;
  197. uint8 *pubData = NULL;
  198. int cubData = 0;
  199. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  200. if ( bRet )
  201. {
  202. Assert( k_EGCSQLType_double == m_pResultSet->GetColumnType( unColumn ) );
  203. AssertMsg2( sizeof( double ) == cubData, "GetValue expected %llu bytes, found %d", (uint64)sizeof( double ), cubData );
  204. if ( sizeof( double ) != cubData )
  205. return false;
  206. *pdVal = *( (double *) pubData );
  207. }
  208. return bRet;
  209. }
  210. //-----------------------------------------------------------------------------
  211. // Purpose: Gets int data for a field in this record
  212. // Input: unColumn - field to get
  213. // pVal - pointer to fill in with data
  214. // Output: true if successful, false if data not present or not of correct type
  215. //-----------------------------------------------------------------------------
  216. bool CSQLRecord::BGetByteValue( uint32 unColumn, byte *pVal )
  217. {
  218. Assert( pVal );
  219. *pVal = 0;
  220. uint8 *pubData = NULL;
  221. int cubData = 0;
  222. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  223. if ( bRet )
  224. {
  225. Assert( k_EGCSQLType_int8 == m_pResultSet->GetColumnType( unColumn ) );
  226. AssertMsg1( 1 == cubData, "GetValue expected 1 bytes, found %d", cubData );
  227. if ( 1 != cubData )
  228. return false;
  229. *pVal = *( (byte *) pubData );
  230. }
  231. return bRet;
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Purpose: Gets int data for a field in this record
  235. // Input: unColumn - field to get
  236. // pVal - pointer to fill in with data
  237. // Output: true if successful, false if data not present or not of correct type
  238. //-----------------------------------------------------------------------------
  239. bool CSQLRecord::BGetBoolValue( uint32 unColumn, bool *pVal )
  240. {
  241. int32 b;
  242. if ( !BGetIntValue( unColumn, &b ) )
  243. return false;
  244. // convert to boolean
  245. *pVal = ( b != 0 );
  246. return true;
  247. }
  248. //-----------------------------------------------------------------------------
  249. // Purpose: Gets int16 data for a field in this record
  250. // Input: unColumn - field to get
  251. // pnVal - pointer to fill in with data
  252. // Output: true if successful, false if data not present or not of correct type
  253. //-----------------------------------------------------------------------------
  254. bool CSQLRecord::BGetInt16Value( uint32 unColumn, int16 *pnVal )
  255. {
  256. Assert( pnVal );
  257. *pnVal = 0;
  258. uint8 *pubData = NULL;
  259. int cubData = 0;
  260. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  261. if ( bRet )
  262. {
  263. Assert( k_EGCSQLType_int16 == m_pResultSet->GetColumnType( unColumn ) );
  264. AssertMsg1( 2 == cubData, "GetValue expected 2 bytes, found %d", cubData );
  265. if ( 2 != cubData )
  266. return false;
  267. *pnVal = *( (int16 *) pubData );
  268. }
  269. return bRet;
  270. }
  271. //-----------------------------------------------------------------------------
  272. // Purpose: Gets int64 data for a field in this record
  273. // Input: unColumn - field to get
  274. // puVal - pointer to fill in with data
  275. // Output: true if successful, false if data not present or not of correct type
  276. //-----------------------------------------------------------------------------
  277. bool CSQLRecord::BGetInt64Value( uint32 unColumn, int64 *puVal )
  278. {
  279. Assert( puVal );
  280. *puVal = 0;
  281. uint8 *pubData = NULL;
  282. int cubData = 0;
  283. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  284. if ( bRet )
  285. {
  286. Assert( k_EGCSQLType_int64 == m_pResultSet->GetColumnType( unColumn ) );
  287. AssertMsg1( 8 == cubData, "GetValue expected 8 bytes, found %d", cubData );
  288. if ( 8 != cubData )
  289. return false;
  290. *puVal = *( (int64 *) pubData );
  291. }
  292. return bRet;
  293. }
  294. //-----------------------------------------------------------------------------
  295. // Purpose: Gets uint64 data for a field in this record
  296. // Input: unColumn - field to get
  297. // puVal - pointer to fill in with data
  298. // Output: true if successful, false if data not present or not of correct type
  299. //-----------------------------------------------------------------------------
  300. bool CSQLRecord::BGetUint64Value( uint32 unColumn, uint64 *puVal )
  301. {
  302. Assert( puVal );
  303. *puVal = 0;
  304. uint8 *pubData = NULL;
  305. int cubData = 0;
  306. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  307. if ( bRet )
  308. {
  309. Assert( k_EGCSQLType_int64 == m_pResultSet->GetColumnType( unColumn ) );
  310. AssertMsg1( 8 == cubData, "GetValue expected 8 bytes, found %d", cubData );
  311. if ( 8 != cubData )
  312. return false;
  313. *puVal = *( (uint64 *) pubData );
  314. }
  315. return bRet;
  316. }
  317. //-----------------------------------------------------------------------------
  318. // Purpose: Gets uint32 data for a field in this record
  319. // Input: unColumn - field to get
  320. // puVal - pointer to fill in with data
  321. // Output: true if successful, false if data not present or not of correct type
  322. //-----------------------------------------------------------------------------
  323. bool CSQLRecord::BGetUint32Value( uint32 unColumn, uint32 *puVal )
  324. {
  325. Assert( puVal );
  326. *puVal = 0;
  327. uint8 *pubData = NULL;
  328. int cubData = 0;
  329. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  330. if ( bRet )
  331. {
  332. Assert( k_EGCSQLType_int32 == m_pResultSet->GetColumnType( unColumn ) );
  333. AssertMsg1( 4 == cubData, "GetValue expected 4 bytes, found %d", cubData );
  334. if ( 4 != cubData )
  335. return false;
  336. *puVal = *( (uint32 *) pubData );
  337. }
  338. return bRet;
  339. }
  340. //-----------------------------------------------------------------------------
  341. // Purpose: Gets uint16 data for a field in this record
  342. // Input: unColumn - field to get
  343. // puVal - pointer to fill in with data
  344. // Output: true if successful, false if data not present or not of correct type
  345. //-----------------------------------------------------------------------------
  346. bool CSQLRecord::BGetUint16Value( uint32 unColumn, uint16 *puVal )
  347. {
  348. Assert( puVal );
  349. *puVal = 0;
  350. uint8 *pubData = NULL;
  351. int cubData = 0;
  352. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  353. if ( bRet )
  354. {
  355. Assert( k_EGCSQLType_int16 == m_pResultSet->GetColumnType( unColumn ) );
  356. AssertMsg1( 2 == cubData, "GetValue expected 2 bytes, found %d", cubData );
  357. if ( 2 != cubData )
  358. return false;
  359. *puVal = *( (uint16 *) pubData );
  360. }
  361. return bRet;
  362. }
  363. //-----------------------------------------------------------------------------
  364. // Purpose: Gets uint8 data for a field in this record
  365. // Input: unColumn - field to get
  366. // puVal - pointer to fill in with data
  367. // Output: true if successful, false if data not present or not of correct type
  368. //-----------------------------------------------------------------------------
  369. bool CSQLRecord::BGetUint8Value( uint32 unColumn, uint8 *puVal )
  370. {
  371. Assert( puVal );
  372. *puVal = 0;
  373. uint8 *pubData = NULL;
  374. int cubData = 0;
  375. bool bRet = BGetColumnData( unColumn, &pubData, &cubData );
  376. if ( bRet )
  377. {
  378. Assert( k_EGCSQLType_int8 == m_pResultSet->GetColumnType( unColumn ) );
  379. AssertMsg1( 1 == cubData, "GetValue expected 1 byte, found %d", cubData );
  380. if ( 1 != cubData )
  381. return false;
  382. *puVal = *( (uint8 *) pubData );
  383. }
  384. return bRet;
  385. }
  386. //-----------------------------------------------------------------------------
  387. // Purpose: Validates column index
  388. // Input: unColumn - field to validate
  389. // Output: true if valid, false otherwise
  390. //-----------------------------------------------------------------------------
  391. bool CSQLRecord::BValidateColumnIndex( uint32 unColumn )
  392. {
  393. if ( unColumn >= m_pResultSet->GetColumnCount() )
  394. {
  395. AssertMsg2( false, "CSQLRecord::BValidateColumnIndex: invalid column index %d. # columns: %d", unColumn,
  396. m_pResultSet->GetColumnCount() );
  397. return false;
  398. }
  399. return true;
  400. }
  401. //-----------------------------------------------------------------------------
  402. // Purpose: Advances the CSQLRecord to the next row
  403. // Output: returns false if this call would advance the record past the last row.
  404. // And makes the record invalid.
  405. //-----------------------------------------------------------------------------
  406. bool CSQLRecord::NextRow()
  407. {
  408. Assert( m_pResultSet );
  409. m_unRow++;
  410. if( m_unRow >= m_pResultSet->GetRowCount() )
  411. m_pResultSet = NULL;
  412. return IsValid();
  413. }
  414. //-----------------------------------------------------------------------------
  415. // Purpose: Render a field to a buffer
  416. // Input: unColumn - field to render
  417. // cchBuffer - size of render buffer
  418. // pchBuffer - buffer to render into
  419. //-----------------------------------------------------------------------------
  420. void CSQLRecord::RenderField( uint32 unColumn, int cchBuffer, char *pchBuffer )
  421. {
  422. Q_strncpy( pchBuffer, "", cchBuffer );
  423. uint8 *pubData;
  424. int cubData;
  425. if ( !BGetColumnData( unColumn, &pubData, &cubData ) )
  426. return;
  427. // Get the column info and figure out how to interpret the data
  428. ConvertFieldToText( m_pResultSet->GetColumnType( unColumn ), pubData, cubData, pchBuffer, cchBuffer, false );
  429. }
  430. //-----------------------------------------------------------------------------
  431. // Purpose: Copies a CSQLRecord to CRecordBase
  432. //-----------------------------------------------------------------------------
  433. bool CSQLRecord::BWriteToRecord( CRecordBase *pRecord, const CColumnSet & csWriteFields )
  434. {
  435. bool bSuccess = true;
  436. FOR_EACH_COLUMN_IN_SET( csWriteFields, unSQLColumn )
  437. {
  438. uint32 unRecordColumn = csWriteFields.GetColumn( unSQLColumn );
  439. uint8 *pubData;
  440. size_t cubData;
  441. if( !BGetColumnData( unSQLColumn, &pubData, &cubData ) )
  442. {
  443. bSuccess = false;
  444. }
  445. else
  446. {
  447. bSuccess = pRecord->BSetField( unRecordColumn, pubData, cubData ) && bSuccess;
  448. }
  449. }
  450. return bSuccess;
  451. }
  452. } // namespace GCSDK