Leaked source code of windows server 2003
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.

713 lines
22 KiB

  1. // Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1993 Microsoft Corporation,
  3. // All rights reserved.
  4. // This source code is only intended as a supplement to the
  5. // Microsoft Foundation Classes Reference and Microsoft
  6. // QuickHelp and/or WinHelp documentation provided with the library.
  7. // See these sources for detailed information regarding the
  8. // Microsoft Foundation Classes product.
  9. #ifndef __AFXDB_H__
  10. #define __AFXDB_H__
  11. #ifndef __AFXWIN_H__
  12. #include <afxext.h>
  13. #endif
  14. /////////////////////////////////////////////////////////////////////////////
  15. // AFXDB - MFC SQL/ODBC/Database support
  16. // Classes declared in this file
  17. //CException
  18. class CDBException; // abnormal return value
  19. //CFieldExchange
  20. class CFieldExchange; // Recordset Field Exchange
  21. //CObject
  22. class CDatabase; // Connecting to databases
  23. class CRecordset; // Data result sets
  24. //CObject
  25. //CCmdTarget;
  26. //CWnd
  27. //CView
  28. //CScrollView
  29. //CFormView
  30. class CRecordView; // view records with a form
  31. // Non CObject classes
  32. struct CRecordsetStatus;
  33. struct CFieldInfo;
  34. /////////////////////////////////////////////////////////////////////////////
  35. // include standard SQL/ODBC "C" APIs
  36. #include <sql.h> // core
  37. #include <sqlext.h> // extensions
  38. // ODBC helpers
  39. // return code left in 'nRetCode'
  40. #define AFX_SQL_ASYNC(prs, SQLFunc) do { ASSERT(!CDatabase::InWaitForDataSource()); \
  41. while ((nRetCode = (SQLFunc)) == SQL_STILL_EXECUTING) \
  42. prs->OnWaitForDataSource(TRUE); \
  43. prs->OnWaitForDataSource(FALSE); } while (0)
  44. #define AFX_SQL_SYNC(SQLFunc) do { ASSERT(!CDatabase::InWaitForDataSource()); \
  45. nRetCode = SQLFunc; } while (0)
  46. // Max display length in chars of timestamp (date & time) value
  47. #define TIMESTAMP_PRECISION 23
  48. // AFXDLL support
  49. #undef AFXAPP_DATA
  50. #define AFXAPP_DATA AFXAPIEX_DATA
  51. // Miscellaneous sizing info
  52. #define MAX_CURRENCY 30 // Max size of Currency($) string
  53. #define MAX_TNAME_LEN 64 // Max size of table names
  54. #define MAX_FNAME_LEN 64 // Max size of field names
  55. #define MAX_DBNAME_LEN 32 // Max size of a database name
  56. #define MAX_DNAME_LEN 256 // Max size of Recordset names
  57. #define MAX_CONNECT_LEN 512 // Max size of Connect string
  58. #define MAX_CURSOR_NAME 18 // Max size of a cursor name
  59. // Max size for CString (incl. zero term.) and CByteArray
  60. #define MAXINT 32767
  61. // Timeout and net wait defaults
  62. #define DEFAULT_LOGIN_TIMEOUT 15 // seconds to before fail on connect
  63. #define DEFAULT_QUERY_TIMEOUT 15 // seconds to before fail waiting for results
  64. #define DEFAULT_MAX_WAIT_FOR_DATASOURCE 250 // milliseconds. Give DATASOURCE 1/4 second to respond
  65. #define DEFAULT_MIN_WAIT_FOR_DATASOURCE 50 // milliseconds. Start value for min wait heuristic
  66. // Field Flags, used to indicate status of fields
  67. #define AFX_SQL_FIELD_FLAG_DIRTY 0x1
  68. #define AFX_SQL_FIELD_FLAG_NULL 0x2
  69. /////////////////////////////////////////////////////////////////////////////
  70. // CDBException - something gone wrong
  71. // Dbkit extended error codes
  72. #define AFX_SQL_ERROR 1000
  73. #define AFX_SQL_ERROR_CONNECT_FAIL AFX_SQL_ERROR+1
  74. #define AFX_SQL_ERROR_RECORDSET_FORWARD_ONLY AFX_SQL_ERROR+2
  75. #define AFX_SQL_ERROR_EMPTY_COLUMN_LIST AFX_SQL_ERROR+3
  76. #define AFX_SQL_ERROR_FIELD_SCHEMA_MISMATCH AFX_SQL_ERROR+4
  77. #define AFX_SQL_ERROR_ILLEGAL_MODE AFX_SQL_ERROR+5
  78. #define AFX_SQL_ERROR_MULTIPLE_ROWS_AFFECTED AFX_SQL_ERROR+6
  79. #define AFX_SQL_ERROR_NO_CURRENT_RECORD AFX_SQL_ERROR+7
  80. #define AFX_SQL_ERROR_NO_ROWS_AFFECTED AFX_SQL_ERROR+8
  81. #define AFX_SQL_ERROR_RECORDSET_READONLY AFX_SQL_ERROR+9
  82. #define AFX_SQL_ERROR_SQL_NO_TOTAL AFX_SQL_ERROR+10
  83. #define AFX_SQL_ERROR_ODBC_LOAD_FAILED AFX_SQL_ERROR+11
  84. #define AFX_SQL_ERROR_DYNASET_NOT_SUPPORTED AFX_SQL_ERROR+12
  85. #define AFX_SQL_ERROR_SNAPSHOT_NOT_SUPPORTED AFX_SQL_ERROR+13
  86. #define AFX_SQL_ERROR_API_CONFORMANCE AFX_SQL_ERROR+14
  87. #define AFX_SQL_ERROR_SQL_CONFORMANCE AFX_SQL_ERROR+15
  88. #define AFX_SQL_ERROR_NO_DATA_FOUND AFX_SQL_ERROR+16
  89. #define AFX_SQL_ERROR_ROW_UPDATE_NOT_SUPPORTED AFX_SQL_ERROR+17
  90. #define AFX_SQL_ERROR_ODBC_V2_REQUIRED AFX_SQL_ERROR+18
  91. #define AFX_SQL_ERROR_NO_POSITIONED_UPDATES AFX_SQL_ERROR+19
  92. #define AFX_SQL_ERROR_LOCK_MODE_NOT_SUPPORTED AFX_SQL_ERROR+20
  93. #define AFX_SQL_ERROR_DATA_TRUNCATED AFX_SQL_ERROR+21
  94. #define AFX_SQL_ERROR_ROW_FETCH AFX_SQL_ERROR+22
  95. #define AFX_SQL_ERROR_MAX AFX_SQL_ERROR+23
  96. class CDBException : public CException
  97. {
  98. DECLARE_DYNAMIC(CDBException)
  99. // Attributes
  100. public:
  101. RETCODE m_nRetCode;
  102. CString m_strError;
  103. CString m_strStateNativeOrigin;
  104. // Implementation (use AfxThrowDBException to create)
  105. public:
  106. CDBException(RETCODE nRetCode = SQL_SUCCESS);
  107. void BuildErrorString(CDatabase* pdb, HSTMT hstmt);
  108. void Empty();
  109. virtual ~CDBException();
  110. #ifdef _DEBUG
  111. virtual void AssertValid() const;
  112. void TraceErrorMessage(LPCTSTR szTrace) const;
  113. #endif // _DEBUG
  114. };
  115. void AFXAPI AfxThrowDBException(RETCODE nRetCode, CDatabase* pdb,
  116. HSTMT hstmt);
  117. //////////////////////////////////////////////////////////////////////////////
  118. // CLongBinary - a Long (generally > 32k in length) Binary object
  119. #define AFX_SQL_DEFAULT_LONGBINARY_SIZE 1024
  120. class CLongBinary : public CObject
  121. {
  122. DECLARE_DYNAMIC(CLongBinary)
  123. // Constructors
  124. public:
  125. CLongBinary();
  126. // Attributes
  127. HGLOBAL m_hData;
  128. DWORD m_dwDataLength;
  129. // Implementation
  130. public:
  131. virtual ~CLongBinary();
  132. #ifdef _DEBUG
  133. virtual void AssertValid() const;
  134. virtual void Dump(CDumpContext& dc) const;
  135. #endif //_DEBUG
  136. };
  137. //////////////////////////////////////////////////////////////////////////////
  138. // CDatabase - a SQL Database
  139. class CDatabase : public CObject
  140. {
  141. DECLARE_DYNAMIC(CDatabase)
  142. // Constructors
  143. public:
  144. CDatabase();
  145. virtual BOOL Open(LPCSTR lpszDSN, BOOL bExclusive = FALSE,
  146. BOOL bReadonly = FALSE, LPCSTR lpszConnect = "ODBC;");
  147. virtual void Close();
  148. // Attributes
  149. public:
  150. HDBC m_hdbc;
  151. BOOL IsOpen() const; // Database successfully opened?
  152. BOOL CanUpdate() const;
  153. BOOL CanTransact() const; // Are Transactions supported?
  154. CString GetDatabaseName() const;
  155. const CString& GetConnect() const;
  156. // global state - if waiting for datasource => not normal operations
  157. static BOOL PASCAL InWaitForDataSource();
  158. // Operations
  159. public:
  160. void SetLoginTimeout(DWORD dwSeconds);
  161. void SetQueryTimeout(DWORD dwSeconds);
  162. void SetSynchronousMode(BOOL bSynchronous);
  163. // transaction control
  164. BOOL BeginTrans();
  165. BOOL CommitTrans();
  166. BOOL Rollback();
  167. // direct sql execution
  168. BOOL ExecuteSQL(LPCSTR lpszSQL);
  169. // Cancel asynchronous operation
  170. void Cancel();
  171. // Overridables
  172. public:
  173. // set special options
  174. virtual void OnSetOptions(HSTMT hstmt);
  175. // Give user chance to cancel long operation
  176. virtual void OnWaitForDataSource(BOOL bStillExecuting);
  177. // Implementation
  178. public:
  179. virtual ~CDatabase();
  180. #ifdef _DEBUG
  181. virtual void AssertValid() const;
  182. virtual void Dump(CDumpContext& dc) const;
  183. BOOL m_bTransactionPending;
  184. #endif //_DEBUG
  185. // general error check
  186. virtual BOOL Check(RETCODE nRetCode) const;
  187. CString QuoteName(const char* szName);
  188. BOOL m_bStripTrailingSpaces;
  189. protected:
  190. CString m_strConnect;
  191. int nRefCount;
  192. BOOL m_bUpdatable;
  193. BOOL m_bTransactions;
  194. DWORD m_dwLoginTimeout;
  195. HSTMT m_hstmt;
  196. DWORD m_dwWait;
  197. DWORD m_dwQueryTimeout;
  198. DWORD m_dwMinWaitForDataSource;
  199. DWORD m_dwMaxWaitForDataSource;
  200. BOOL m_bAsync;
  201. char m_chIDQuoteChar;
  202. void ThrowDBException(RETCODE nRetCode);
  203. void AllocConnect();
  204. void Free();
  205. // friend classes that call protected CDatabase overridables
  206. friend class CRecordset;
  207. friend class CFieldExchange;
  208. friend class CDBException;
  209. };
  210. //////////////////////////////// /////////////////////////////////////////////
  211. // Recordset Field exchanged (RFX_)
  212. #define AFX_RFX_INT_PSEUDO_NULL (0x7EE4)
  213. #define AFX_RFX_LONG_PSEUDO_NULL (0x4a4d4120L)
  214. #define AFX_RFX_BYTE_PSEUDO_NULL 255
  215. #define AFX_RFX_SINGLE_PSEUDO_NULL (-9.123e19)
  216. #define AFX_RFX_DOUBLE_PSEUDO_NULL (-9.123e19)
  217. #define AFX_RFX_BOOL_PSEUDO_NULL 2
  218. #define AFX_RFX_DATE_PSEUDO_NULL CTime(0)
  219. #define AFX_RFX_BOOL 1
  220. #define AFX_RFX_BYTE 2
  221. #define AFX_RFX_INT 3
  222. #define AFX_RFX_LONG 4
  223. #define AFX_RFX_SINGLE 6
  224. #define AFX_RFX_DOUBLE 7
  225. #define AFX_RFX_DATE 8
  226. #define AFX_RFX_BINARY 9
  227. #define AFX_RFX_TEXT 10
  228. #define AFX_RFX_LONGBINARY 11
  229. // CFieldExchange - for field exchange
  230. class AFX_STACK_DATA CFieldExchange
  231. {
  232. // Attributes
  233. public:
  234. enum RFX_Operation
  235. {
  236. BindParam, // register users parameters with ODBC SQLSetParam
  237. BindFieldToColumn, // register users fields with ODBC SQLBindCol
  238. Fixup, // Set string lengths, clear status bits
  239. MarkForAddNew,
  240. MarkForUpdate, // Prepare fields and flags for update operation
  241. Name, // append dirty field name
  242. NameValue, // append dirty name=value
  243. Value, // append dirty value or parameter marker
  244. SetFieldDirty, // Set status bit for changed status
  245. SetFieldNull, // Set status bit for null value
  246. IsFieldDirty,// return TRUE if field is dirty
  247. IsFieldNull,// return TRUE if field is marked NULL
  248. IsFieldNullable,// return TRUE if field can hold NULL values
  249. StoreField, // archive values of current record
  250. LoadField, // reload archived values into current record
  251. GetFieldInfoValue, // general info on a field via pv for field
  252. GetFieldInfoOrdinal, // general info on a field via field ordinal
  253. RebindDateParam, // migrate date param values to proxy array before Requery
  254. MaxRFXOperation,
  255. };
  256. UINT m_nOperation; // Type of exchange operation
  257. CRecordset* m_prs; // recordset handle
  258. // Operations
  259. enum FieldType
  260. {
  261. noFieldType,
  262. outputColumn,
  263. param,
  264. };
  265. // Operations (for implementors of RFX procs)
  266. BOOL IsFieldType(UINT* pnField);
  267. // Indicate purpose of subsequent RFX calls
  268. void SetFieldType(UINT nFieldType);
  269. // Implementation
  270. CFieldExchange(UINT nOperation, CRecordset* prs, void* pvField = NULL);
  271. void Default(const char *szName,
  272. void* pv, LONG* plLength, int nCType, UINT cbValue, UINT cbPrecision);
  273. int GetColumnType(int nColumn, UINT* pcbLength = NULL,
  274. int* pnScale = NULL, int* pnNullable = NULL);
  275. // Current type of field
  276. UINT m_nFieldType;
  277. // For GetFieldInfo
  278. CFieldInfo* m_pfi; // GetFieldInfo return struct
  279. BOOL m_bFieldFound; // GetFieldInfo search successful?
  280. // For returning status info for a field
  281. BOOL m_bNull; // return result of IsFieldNull(able)/Dirty operation
  282. BOOL m_bDirty; // return result of IsFieldNull(able)/Dirty operation
  283. CString* m_pstr; // Field name or destination for building various SQL clauses
  284. BOOL m_bField; // Value to set for SetField operation
  285. void* m_pvField; // For indicating an operation on a specific field
  286. CArchive* m_par; // For storing/loading copy buffer
  287. LPCSTR m_lpszSeparator; // append after field names
  288. UINT m_nFields; // count of fields for various operations
  289. UINT m_nParams; // count of fields for various operations
  290. UINT m_nParamFields; // count of fields for various operations
  291. HSTMT m_hstmt; // For SQLSetParam on update statement
  292. };
  293. /////////////////////////////////////////////////////////////////////////////
  294. // Standard RecordSet Field Exchange routines
  295. // text data
  296. void AFXAPI RFX_Text(CFieldExchange* pFX, const char *szName, CString& value,
  297. // Default max length for char and varchar, default datasource type
  298. int nMaxLength = 255, int nColumnType = SQL_VARCHAR);
  299. // boolean data
  300. void AFXAPI RFX_Bool(CFieldExchange* pFX, const char *szName, BOOL& value);
  301. // integer data
  302. void AFXAPI RFX_Long(CFieldExchange* pFX, const char *szName, long& value);
  303. void AFXAPI RFX_Int(CFieldExchange* pFX, const char *szName, int& value);
  304. void AFXAPI RFX_Single(CFieldExchange* pFX, const char *szName, float& value);
  305. void AFXAPI RFX_Double(CFieldExchange* pFX, const char *szName, double& value);
  306. // date and time
  307. void AFXAPI RFX_Date(CFieldExchange* pFX, const char *szName, CTime& value);
  308. // Binary data
  309. void AFXAPI RFX_Binary(CFieldExchange* pFX, const char *szName, CByteArray& value,
  310. // Default max length is for binary and varbinary
  311. int nMaxLength = 255);
  312. void AFXAPI RFX_Byte(CFieldExchange* pFX, const char *szName, BYTE& value);
  313. void AFXAPI RFX_LongBinary(CFieldExchange* pFX, const char *szName, CLongBinary& value);
  314. /////////////////////////////////////////////////////////////////////////////
  315. // Database Dialog Data Exchange cover routines
  316. // Cover routines provide database semantics on top of DDX routines
  317. // simple text operations
  318. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, BYTE& value, CRecordset* pRecordset);
  319. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, int& value, CRecordset* pRecordset);
  320. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, UINT& value, CRecordset* pRecordset);
  321. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, long& value, CRecordset* pRecordset);
  322. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, DWORD& value, CRecordset* pRecordset);
  323. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset);
  324. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, double& value, CRecordset* pRecordset);
  325. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, float& value, CRecordset* pRecordset);
  326. // special control types
  327. void AFXAPI DDX_FieldCheck(CDataExchange* pDX, int nIDC, int& value, CRecordset* pRecordset);
  328. void AFXAPI DDX_FieldRadio(CDataExchange* pDX, int nIDC, int& value, CRecordset* pRecordset);
  329. void AFXAPI DDX_FieldLBString(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset);
  330. void AFXAPI DDX_FieldCBString(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset);
  331. #if (WINVER >= 0x030a)
  332. void AFXAPI DDX_FieldLBStringExact(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset);
  333. void AFXAPI DDX_FieldCBStringExact(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset);
  334. #endif
  335. //////////////////////////////////////////////////////////////////////////////
  336. // CRecordset - the result of a SQL Statement
  337. #define AFX_MOVE_FIRST 0x80000000L
  338. #define AFX_MOVE_PREVIOUS -1L
  339. #define AFX_MOVE_REFRESH 0L
  340. #define AFX_MOVE_NEXT +1L
  341. #define AFX_MOVE_LAST 0x7fffffffL
  342. class CRecordset : public CObject
  343. {
  344. DECLARE_DYNAMIC(CRecordset)
  345. // Constructor
  346. protected:
  347. CRecordset(CDatabase* pDatabase = NULL);
  348. public:
  349. virtual ~CRecordset();
  350. enum OpenType
  351. {
  352. dynaset,
  353. snapshot,
  354. forwardOnly
  355. };
  356. enum OpenOptions
  357. {
  358. none = 0x0,
  359. readOnly = 0x0004,
  360. appendOnly = 0x0008,
  361. optimizeBulkAdd = 0x2000, // Use prepared HSTMT for multiple AddNews, dirty fields must not change.
  362. firstBulkAdd = 0x4000, // INTERNAL to MFC, don't specify on Open.
  363. };
  364. virtual BOOL Open(UINT nOpenType = snapshot, LPCSTR lpszSQL = NULL, DWORD dwOptions = none);
  365. virtual void Close();
  366. // Attributes
  367. public:
  368. HSTMT m_hstmt; // Source statement for this resultset
  369. CDatabase* m_pDatabase; // Source database for this resultset
  370. CString m_strFilter; // Where clause
  371. CString m_strSort; // Order By Clause
  372. BOOL CanAppend() const; // Can AddNew be called?
  373. BOOL CanRestart() const; // Can Requery be called to restart a query?
  374. BOOL CanScroll() const; // Can MovePrev and MoveFirst be called?
  375. BOOL CanTransact() const; // Are Transactions supported?
  376. BOOL CanUpdate() const; // Can Edit/AddNew/Delete be called?
  377. const CString& GetSQL() const; // SQL executed for this recordset
  378. const CString& GetTableName() const; // Table name
  379. BOOL IsOpen() const; // Recordset successfully opened?
  380. BOOL IsBOF() const; // Beginning Of File
  381. BOOL IsEOF() const; // End Of File
  382. BOOL IsDeleted() const; // On a deleted record
  383. BOOL IsFieldDirty(void *pv); // has field been updated?
  384. BOOL IsFieldNull(void *pv); // is field NULL valued?
  385. BOOL IsFieldNullable(void *pv); // can field be set to a NULL value
  386. long GetRecordCount() const; // Records seen so far or -1 if unknown
  387. void GetStatus(CRecordsetStatus& rStatus) const;
  388. // Operations
  389. public:
  390. // cursor operations
  391. void MoveNext();
  392. void MovePrev();
  393. void MoveFirst();
  394. void MoveLast();
  395. virtual void Move(long lRows);
  396. // edit buffer operations
  397. void AddNew(); // add new record at the end
  398. void Edit(); // start editing
  399. BOOL Update(); // update it
  400. void Delete(); // delete the current record
  401. // field operations
  402. void SetFieldDirty(void *pv, BOOL bDirty = TRUE);
  403. void SetFieldNull(void *pv, BOOL bNull = TRUE);
  404. // locking control during Edit
  405. enum LockMode
  406. {
  407. optimistic,
  408. pessimistic,
  409. };
  410. void SetLockingMode(UINT nMode);
  411. // Recordset operations
  412. virtual BOOL Requery(); // Re-execute query based on new params
  413. // Cancel asynchronous operation
  414. void Cancel();
  415. // Overridables
  416. public:
  417. // Get default connect string
  418. virtual CString GetDefaultConnect();
  419. // Get SQL to execute
  420. virtual CString GetDefaultSQL() = 0;
  421. // set special options
  422. virtual void OnSetOptions(HSTMT hstmt);
  423. // Give user chance to cancel long operation
  424. virtual void OnWaitForDataSource(BOOL bStillExecuting);
  425. // for recordset field exchange
  426. virtual void DoFieldExchange(CFieldExchange* pFX) = 0;
  427. // Implementation
  428. public:
  429. #ifdef _DEBUG
  430. virtual void AssertValid() const;
  431. virtual void Dump(CDumpContext& dc) const;
  432. #endif //_DEBUG
  433. virtual BOOL Check(RETCODE nRetCode) const; // general error check
  434. void InitRecord();
  435. virtual void PreBindFields(); // called before data fields are bound
  436. UINT m_nFields; // number of RFX fields
  437. UINT m_nParams; // number of RFX params
  438. // RFX Operations on fields of CRecordset
  439. UINT BindParams(HSTMT hstmt);
  440. void RebindDateParams(HSTMT hstmt);
  441. UINT BindFieldsToColumns();
  442. void Fixups();
  443. UINT AppendNames(CString* pstr, LPCSTR szSeparator);
  444. UINT AppendValues(HSTMT hstmt, CString* pstr, LPCSTR szSeparator);
  445. UINT AppendNamesValues(HSTMT hstmt, CString* pstr, LPCSTR szSeparator);
  446. void StoreFields();
  447. void LoadFields();
  448. void MarkForAddNew();
  449. void MarkForUpdate();
  450. BOOL GetFieldInfo(void* pv, CFieldInfo* pfi);
  451. BOOL GetFieldInfo(UINT nField, CFieldInfo* pfi);
  452. // RFX operation helper functions
  453. BOOL UnboundFieldInfo(UINT nField, CFieldInfo* pfi);
  454. void ThrowDBException(RETCODE nRetCode, HSTMT hstmt = SQL_NULL_HSTMT);
  455. CMemFile* m_pmemfile; // For saving copy buffer
  456. CArchive* m_par; // For saving copy buffer
  457. void AllocFlags();
  458. BYTE GetFieldFlags(UINT nField, UINT nFieldType = CFieldExchange::outputColumn);
  459. void SetFieldFlags(UINT nField, BYTE bFlags, UINT nFieldType = CFieldExchange::outputColumn);
  460. void ClearFieldFlags(UINT nField, BYTE bFlags, UINT nFieldType = CFieldExchange::outputColumn);
  461. LONG* GetFieldLength(CFieldExchange* pFX);
  462. BOOL IsFieldFlagNull(UINT nField, UINT nFieldType);
  463. BOOL IsFieldFlagDirty(UINT nField, UINT nFieldType);
  464. void** m_pvFieldProxy;
  465. void** m_pvParamProxy;
  466. protected:
  467. UINT m_nOpenType;
  468. enum EditMode
  469. {
  470. noMode,
  471. edit,
  472. addnew
  473. };
  474. UINT m_nEditMode;
  475. BOOL m_bEOFSeen;
  476. long m_lRecordCount;
  477. long m_lCurrentRecord;
  478. CString m_strCursorName;
  479. // Perform operation based on m_nEditMode
  480. BOOL UpdateInsertDelete();
  481. void ReleaseCopyBuffer();
  482. BOOL m_nLockMode; // Control concurrency for Edit()
  483. HSTMT m_hstmtUpdate;
  484. BOOL m_bRecordsetDb;
  485. public:
  486. DWORD m_dwOptions; // Cache options specified on Open.
  487. protected:
  488. BOOL m_bBOF;
  489. BOOL m_bEOF;
  490. BOOL m_bUpdatable; // Is recordset updatable?
  491. BOOL m_bAppendable;
  492. CString m_strSQL; // SQL statement for recordset
  493. CString m_strTableName; // source table of recordset
  494. BOOL m_bScrollable; // supports MovePrev
  495. BOOL m_bDeleted;
  496. DWORD m_dwWait;
  497. UINT m_nFieldsBound;
  498. BYTE* m_pbFieldFlags;
  499. LONG* m_plFieldLength;
  500. BYTE* m_pbParamFlags;
  501. LONG* m_plParamLength;
  502. BOOL m_bExtendedFetch;
  503. void BuildTableQuery();
  504. friend class CFieldExchange;
  505. friend class CRecordView;
  506. };
  507. #define AFX_CURRENT_RECORD_UNDEFINED -2
  508. #define AFX_CURRENT_RECORD_BOF -1
  509. // For returning status for a recordset
  510. struct CRecordsetStatus
  511. {
  512. long m_lCurrentRecord; // -2=Unknown,-1=BOF,0=1st record. . .
  513. BOOL m_bRecordCountFinal;// Have we counted all records?
  514. };
  515. // For returning field info on RFX fields
  516. struct CFieldInfo
  517. {
  518. // For ID'ing field
  519. UINT nField; // Field number
  520. CString strName; // Field name
  521. void* pv; // Address of value for field
  522. // Return info GetFieldInfo
  523. UINT nDataType; // data type of field (BOOL, BYTE, etc)
  524. DWORD dwSize; // Max size for field data
  525. };
  526. /////////////////////////////////////////////////////////////////////////////
  527. // CRecordView - form for viewing data records
  528. class CRecordView : public CFormView
  529. {
  530. DECLARE_DYNAMIC(CRecordView)
  531. // Construction
  532. protected: // must derive your own class
  533. CRecordView(LPCSTR lpszTemplateName);
  534. CRecordView(UINT nIDTemplate);
  535. // Attributes
  536. public:
  537. virtual CRecordset* OnGetRecordset() = 0;
  538. BOOL IsOnLastRecord();
  539. BOOL IsOnFirstRecord();
  540. // Operations
  541. public:
  542. virtual BOOL OnMove(UINT nIDMoveCommand);
  543. // Implementation
  544. public:
  545. virtual ~CRecordView();
  546. #ifdef _DEBUG
  547. virtual void AssertValid() const;
  548. virtual void Dump(CDumpContext& dc) const;
  549. #endif
  550. virtual void OnInitialUpdate();
  551. protected:
  552. BOOL m_bOnFirstRecord;
  553. BOOL m_bOnLastRecord;
  554. //{{AFX_MSG(CRecordView)
  555. afx_msg void OnUpdateRecordFirst(CCmdUI* pCmdUI);
  556. afx_msg void OnUpdateRecordPrev(CCmdUI* pCmdUI);
  557. afx_msg void OnUpdateRecordNext(CCmdUI* pCmdUI);
  558. afx_msg void OnUpdateRecordLast(CCmdUI* pCmdUI);
  559. //}}AFX_MSG
  560. DECLARE_MESSAGE_MAP()
  561. };
  562. #undef AFXAPP_DATA
  563. #define AFXAPP_DATA NEAR
  564. /////////////////////////////////////////////////////////////////////////////
  565. // Inline function declarations
  566. #ifdef _AFX_ENABLE_INLINES
  567. #define _AFXDBCORE_INLINE inline
  568. #define _AFXDBRFX_INLINE inline
  569. #define _AFXDBVIEW_INLINE inline
  570. #include <afxdb.inl>
  571. #undef _AFXDBVIEW_INLINE
  572. #undef _AFXDBCORE_INLINE
  573. #undef _AFXDBRFX_INLINE
  574. #endif
  575. //////////////////////////////////////////////////////////////////////////////
  576. #endif //__AFXDB_H__