Source code of Windows XP (NT5)
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.

757 lines
12 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name :
  4. odbcconn.hxx
  5. Abstract:
  6. This module declares the class ODBC_CONNECTION used for odbc
  7. connectivity. It also declares the class ODBC_PARAMETER for
  8. parameter markers used for insertion of data.
  9. Author:
  10. Murali R. Krishnan ( MuraliK ) 16-Feb-1995
  11. Environment:
  12. User Mode
  13. Project:
  14. Internet Services Common DLL
  15. Revision History:
  16. MuraliK 08-Jan-1995 Split Dynamic Load ODBC module.
  17. --*/
  18. # ifndef _ODBCCONN_HXX_
  19. # define _ODBCCONN_HXX_
  20. /************************************************************
  21. * Include Headers
  22. ************************************************************/
  23. //
  24. // SQL-ODBC interface headers
  25. //
  26. # include "sql.h"
  27. # include "sqlext.h"
  28. /************************************************************
  29. * Macros Definitions
  30. ************************************************************/
  31. //
  32. // Default connection pool timeout
  33. //
  34. #define IDC_POOL_TIMEOUT 30
  35. /************************************************************
  36. * Dynamic Load support
  37. ************************************************************/
  38. //
  39. // Support Old users of LoadODBC
  40. //
  41. inline
  42. BOOL
  43. LoadODBC(
  44. VOID
  45. )
  46. {
  47. return ( DynLoadODBC() );
  48. } // LoadODBC()
  49. /************************************************************
  50. * Type Definitions
  51. ************************************************************/
  52. /*++
  53. class ODBC_PARAMETER
  54. This class encapsulates data related to ODBC parameter markers
  55. to be used for binding purposes.
  56. Information about a parameter include:
  57. Parameter Number - Index of the parameter in the columns of table.
  58. Parameter Type - Indicates direction of data tfr(In, Out, In/Out)
  59. C Type - Specifies the C Equivalent data struct.
  60. Sql Type - Specifies the SQL Equivalent data struct.
  61. Precision - Gives the precision of the column
  62. Scale - Gives the scale for display of parameter values
  63. Value - Specifies the pointer to memory containing
  64. the value of the parameter
  65. MaxCbValue - Specifies the maximum bytes of data that can
  66. be stored in the value buffer
  67. CbValue - Provides a counter for bytes of data used
  68. up in the binding process.
  69. --*/
  70. class ODBC_PARAMETER {
  71. public:
  72. ODBC_PARAMETER(
  73. IN WORD iParameter,
  74. IN SWORD fParamType,
  75. IN SWORD CType,
  76. IN SWORD sqlType,
  77. IN UDWORD cbPrecision = 0
  78. ) : m_iParameter ( iParameter ),
  79. m_paramType ( fParamType ),
  80. m_CType ( CType ),
  81. m_SqlType ( sqlType ),
  82. m_cbColPrecision( cbPrecision ),
  83. m_ibScale ( 0 ),
  84. m_pValue ( NULL ),
  85. m_cbValue ( 0 ),
  86. m_cbValueMax ( 0 )
  87. {}
  88. ~ODBC_PARAMETER(
  89. )
  90. {
  91. if ( m_pValue != NULL )
  92. {
  93. delete m_pValue;
  94. m_pValue = NULL;
  95. }
  96. }
  97. HRESULT
  98. SetValueBuffer(
  99. IN SDWORD cbMaxSize,
  100. IN SDWORD cbValue
  101. )
  102. {
  103. m_pValue = ( PTR ) new CHAR[ cbMaxSize ];
  104. if ( m_pValue != NULL)
  105. {
  106. memset( m_pValue, 0, cbMaxSize);
  107. m_cbValueMax = cbMaxSize;
  108. m_cbValue = cbValue;
  109. return S_OK;
  110. }
  111. return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  112. } // SetValueBuffer()
  113. HRESULT
  114. CopyValue(
  115. IN PVOID pvValue,
  116. IN SDWORD cbValue
  117. )
  118. {
  119. if ( cbValue <= m_cbValueMax )
  120. {
  121. memcpy( m_pValue, pvValue, cbValue );
  122. }
  123. else
  124. {
  125. return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
  126. }
  127. return S_OK;
  128. } // CopyValue()
  129. HRESULT
  130. CopyValue(
  131. IN LPCSTR pszValue
  132. )
  133. {
  134. //
  135. // always copy including the null character
  136. //
  137. return ( CopyValue( ( PVOID ) pszValue,
  138. strlen( pszValue ) + 1 ) );
  139. }
  140. HRESULT
  141. CopyValue(
  142. IN LPCWSTR pwszValue
  143. );
  144. HRESULT
  145. CopyValue(
  146. IN LPSYSTEMTIME lpSystemTime
  147. );
  148. HRESULT
  149. CopyValue(
  150. IN DWORD dwValue
  151. )
  152. {
  153. return ( CopyValue( ( PVOID ) &dwValue,
  154. sizeof( DWORD ) ) );
  155. }
  156. WORD
  157. QueryParamNumber(
  158. VOID
  159. ) const
  160. {
  161. return ( m_iParameter );
  162. }
  163. SWORD
  164. QueryParamType(
  165. VOID
  166. ) const
  167. {
  168. return ( m_paramType );
  169. }
  170. SWORD
  171. QueryCType(
  172. VOID
  173. ) const
  174. {
  175. return ( m_CType );
  176. }
  177. SWORD
  178. QuerySqlType(
  179. VOID
  180. ) const
  181. {
  182. return ( m_SqlType);
  183. }
  184. UDWORD
  185. QueryPrecision(
  186. VOID
  187. ) const
  188. {
  189. return ( m_cbColPrecision );
  190. }
  191. SWORD
  192. QueryScale(
  193. VOID
  194. ) const
  195. {
  196. return ( m_ibScale );
  197. }
  198. PTR
  199. QueryValue(
  200. VOID
  201. ) const
  202. {
  203. return ( m_pValue );
  204. }
  205. SDWORD
  206. QueryMaxCbValue(
  207. VOID
  208. ) const
  209. {
  210. return ( m_cbValueMax );
  211. }
  212. SDWORD
  213. QueryCbValue(
  214. VOID
  215. ) const
  216. {
  217. return ( m_cbValue );
  218. }
  219. SDWORD &
  220. QueryCbValueRef(
  221. VOID
  222. )
  223. {
  224. //
  225. // return a reference to count of bytes rx
  226. //
  227. return ( m_cbValue );
  228. }
  229. RETCODE
  230. Bind(
  231. IN HSTMT hStmt
  232. );
  233. #if DBG
  234. VOID
  235. Print(
  236. VOID
  237. ) const;
  238. #endif // DBG
  239. private:
  240. //
  241. // index or the parameter number
  242. //
  243. WORD m_iParameter;
  244. //
  245. // type of the parameter
  246. //
  247. SWORD m_paramType;
  248. //
  249. // the C data type for this parameter
  250. //
  251. SWORD m_CType;
  252. //
  253. // the SQL data type for this parameter
  254. //
  255. SWORD m_SqlType;
  256. //
  257. // precision of the column
  258. //
  259. UDWORD m_cbColPrecision;
  260. //
  261. // scale of the column
  262. //
  263. SWORD m_ibScale;
  264. //
  265. // pointer to the value
  266. //
  267. PTR m_pValue;
  268. //
  269. // max bytes allowed in pValue
  270. //
  271. SDWORD m_cbValueMax;
  272. //
  273. // count of bytes of value
  274. //
  275. SDWORD m_cbValue;
  276. }; // class ODBC_PARAMETER
  277. typedef ODBC_PARAMETER * PODBC_PARAMETER;
  278. //
  279. // Forwards Declaration
  280. //
  281. class ODBC_CONNECTION;
  282. /*++
  283. class ODBC_STATEMENT:
  284. This class declares an interface for statements using ODBC
  285. connection.
  286. m_hstmt Statement used for execution
  287. m_rc Return code for last ODBC call
  288. m_fPreparedStmt is the statement prepared
  289. --*/
  290. #define ODBC_STATEMENT_SIGNATURE 'TSDO'
  291. #define ODBC_STATEMENT_FREE_SIGNATURE 'fSDO'
  292. class ODBC_STATEMENT {
  293. public:
  294. ODBC_STATEMENT(
  295. IN ODBC_CONNECTION * pOdbcConnection,
  296. IN HSTMT hStmt
  297. ) : m_dwSignature ( ODBC_STATEMENT_SIGNATURE ),
  298. m_hStmt ( hStmt ),
  299. m_pOdbcConnection( pOdbcConnection ),
  300. m_fPreparedStmt ( FALSE ),
  301. m_rc ( SQL_SUCCESS ),
  302. m_astrColNames ( NULL ),
  303. m_astrValues ( NULL ),
  304. m_acbValue ( NULL ),
  305. m_cCols ( 0 )
  306. {}
  307. ~ODBC_STATEMENT();
  308. BOOL
  309. CheckSignature(
  310. VOID
  311. ) const
  312. {
  313. return m_dwSignature == ODBC_STATEMENT_SIGNATURE;
  314. }
  315. RETCODE
  316. QueryErrorCode(
  317. VOID
  318. ) const
  319. {
  320. return ( m_rc );
  321. }
  322. BOOL
  323. IsValid(
  324. VOID
  325. ) const
  326. {
  327. return ( m_fPreparedStmt );
  328. }
  329. HRESULT
  330. PrepareStatement(
  331. IN LPCSTR pszStatement
  332. );
  333. HRESULT
  334. PrepareStatement(
  335. IN LPCWSTR pwszStatement
  336. );
  337. HRESULT
  338. BindParameter(
  339. IN PODBC_PARAMETER pOdbcParam
  340. );
  341. //
  342. // Executes the prepared statement
  343. //
  344. HRESULT
  345. ExecuteStatement(
  346. VOID
  347. );
  348. HRESULT
  349. ExecDirect(
  350. IN LPCSTR pszSqlCommand,
  351. IN DWORD cchSqlCommand
  352. );
  353. HRESULT
  354. ExecDirect(
  355. IN LPCWSTR pszSqlCommand,
  356. IN DWORD cchSqlCommand
  357. );
  358. HRESULT
  359. QueryRowCount(
  360. OUT DWORD * pRows
  361. );
  362. inline
  363. BOOL
  364. GetLastErrorText(
  365. OUT STRA * pstrError
  366. );
  367. inline
  368. BOOL
  369. GetLastErrorTextAsHtml(
  370. OUT STRA * pstrError
  371. );
  372. //
  373. // These allocate an array (0 to cCols-1) containing the row
  374. // name of the result column and the string value of the current
  375. // position in the result set. Each successive call to
  376. // QueryValuesAsStr gets the next row in the result set.
  377. //
  378. HRESULT
  379. QueryColNames(
  380. OUT STRA * * apstrCols,
  381. OUT DWORD * cCols,
  382. IN DWORD cchMaxFieldSize,
  383. OUT BOOL * pfIsSelect
  384. );
  385. HRESULT
  386. QueryValuesAsStr(
  387. OUT STRA * * apstrValues,
  388. OUT DWORD * * apcbValues,
  389. OUT BOOL * pfLast
  390. );
  391. HRESULT
  392. MoreResults(
  393. BOOL * pfMoreResults
  394. );
  395. # if DBG
  396. VOID
  397. Print(
  398. VOID
  399. ) const;
  400. # endif // DBG
  401. VOID FreeColumnMemory( VOID );
  402. VOID *
  403. operator new(
  404. size_t size
  405. )
  406. {
  407. DBG_ASSERT( size == sizeof( ODBC_STATEMENT ) );
  408. DBG_ASSERT( sm_pachOdbcStatements != NULL );
  409. return sm_pachOdbcStatements->Alloc();
  410. }
  411. VOID
  412. operator delete(
  413. VOID * pOdbcStatement
  414. )
  415. {
  416. DBG_ASSERT( pOdbcStatement != NULL );
  417. DBG_ASSERT( sm_pachOdbcStatements != NULL );
  418. DBG_REQUIRE( sm_pachOdbcStatements->Free( pOdbcStatement ) );
  419. }
  420. static
  421. HRESULT
  422. Initialize(
  423. VOID
  424. );
  425. static
  426. VOID
  427. Terminate(
  428. VOID
  429. );
  430. private:
  431. //
  432. // Signature of the class
  433. //
  434. DWORD m_dwSignature;
  435. //
  436. // back pointer to connection
  437. //
  438. ODBC_CONNECTION * m_pOdbcConnection;
  439. //
  440. // set after stmt is prepared
  441. //
  442. BOOL m_fPreparedStmt;
  443. HSTMT m_hStmt;
  444. RETCODE m_rc;
  445. //
  446. // Contains buffers used by QueryColNames and QueryValuesAsStr
  447. //
  448. WORD m_cCols;
  449. STRA * m_astrColNames;
  450. //
  451. // Memory for destination of fetched data
  452. //
  453. STRA * m_astrValues;
  454. //
  455. // Array of byte counts of data placed in m_astrValues
  456. //
  457. LONG * m_acbValue;
  458. //
  459. // Lookaside
  460. //
  461. static ALLOC_CACHE_HANDLER * sm_pachOdbcStatements;
  462. }; // ODBC_STATEMENT()
  463. typedef ODBC_STATEMENT * PODBC_STATEMENT;
  464. /*++
  465. class ODBC_CONNECTION:
  466. This class specifies a logical class to contain the ODBC nuances
  467. and encapsulates relevant data for using ODBC to talk to a
  468. database system.
  469. Data encapsulated includes:
  470. m_henv Environment handle for ODBC connection.
  471. m_hdbc Database connection handle.
  472. m_rc Return code for last ODBC call.
  473. --*/
  474. class ODBC_CONNECTION {
  475. public:
  476. ODBC_CONNECTION()
  477. : m_henv ( SQL_NULL_HENV ),
  478. m_hdbc ( SQL_NULL_HDBC ),
  479. m_fValid ( FALSE ),
  480. m_rc ( SQL_SUCCESS )
  481. {}
  482. ~ODBC_CONNECTION();
  483. //
  484. // Returns the text for the last error that occurred
  485. //
  486. BOOL
  487. GetLastErrorText(
  488. OUT STRA * pstrError,
  489. IN HSTMT hstmt = SQL_NULL_HSTMT,
  490. IN RETCODE rc = SQL_SUCCESS
  491. ) const;
  492. BOOL
  493. GetLastErrorTextAsHtml(
  494. OUT STRA * pstrError,
  495. IN HSTMT hstmt = SQL_NULL_HSTMT,
  496. IN RETCODE rc = SQL_SUCCESS
  497. ) const;
  498. static
  499. BOOL
  500. Success(
  501. IN RETCODE rc
  502. )
  503. {
  504. return ( ( rc == SQL_SUCCESS ) ||
  505. ( rc == SQL_SUCCESS_WITH_INFO ) );
  506. }
  507. BOOL
  508. IsValid(
  509. VOID
  510. ) const
  511. {
  512. return ( m_fValid );
  513. }
  514. RETCODE
  515. QueryErrorCode(
  516. VOID
  517. ) const
  518. {
  519. return ( m_rc );
  520. }
  521. HRESULT
  522. Open(
  523. IN LPCSTR pszDataSource,
  524. IN LPCSTR pszUserName,
  525. IN LPCSTR pszPassword
  526. );
  527. HRESULT
  528. Open(
  529. IN LPCWSTR pwszDataSource,
  530. IN LPCWSTR pwszUserName,
  531. IN LPCWSTR pwszPassword
  532. );
  533. HRESULT
  534. Close(
  535. VOID
  536. );
  537. PODBC_STATEMENT
  538. AllocStatement(
  539. VOID
  540. );
  541. HRESULT
  542. SetConnectOption(
  543. IN UWORD Option,
  544. IN SQLULEN Param
  545. );
  546. BOOL
  547. GetInfo(
  548. IN DWORD fInfoType,
  549. IN PVOID rgbInfoValue,
  550. IN DWORD cbInfoValueMax,
  551. IN OUT DWORD * pcbInfoValue
  552. );
  553. static
  554. DWORD
  555. DisplaySize(
  556. SWORD ColType,
  557. DWORD cchColLength
  558. );
  559. #if DBG
  560. VOID
  561. Print(
  562. VOID
  563. ) const;
  564. #endif // DBG
  565. private:
  566. //
  567. // ODBC specific data members.
  568. //
  569. HENV m_henv;
  570. HDBC m_hdbc;
  571. RETCODE m_rc;
  572. BOOL m_fValid;
  573. }; // ODBC_CONNECTION
  574. typedef ODBC_CONNECTION * PODBC_CONNECTION;
  575. /************************************************************
  576. * Inline Functions
  577. ************************************************************/
  578. inline
  579. BOOL
  580. ODBC_STATEMENT::GetLastErrorText(
  581. OUT STRA * pstrError
  582. )
  583. {
  584. return ( m_pOdbcConnection->GetLastErrorText( pstrError,
  585. m_hStmt,
  586. m_rc ) );
  587. } // ODBC_STATEMENT::GetLastErrorText()
  588. inline
  589. BOOL
  590. ODBC_STATEMENT::GetLastErrorTextAsHtml(
  591. OUT STRA * pstrError
  592. )
  593. {
  594. return ( m_pOdbcConnection->GetLastErrorTextAsHtml( pstrError,
  595. m_hStmt,
  596. m_rc ) );
  597. } // ODBC_STATEMENT::GetLastErrorText()
  598. # endif // _ODBCCONN_HXX_