home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / include / afxdb.h < prev    next >
C/C++ Source or Header  |  1998-06-16  |  35KB  |  1,060 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #ifndef __AFXDB_H__
  12. #define __AFXDB_H__
  13.  
  14. #ifdef _AFX_NO_DB_SUPPORT
  15.     #error Database classes not supported in this library variant.
  16. #endif
  17.  
  18. #ifndef __AFXEXT_H__
  19.     #include <afxext.h>
  20. #endif
  21.  
  22. #ifndef __AFXDB__H__
  23.     #include <afxdb_.h> // shared header DAO database classes
  24. #endif
  25.  
  26. // include standard SQL/ODBC "C" APIs
  27. #ifndef __SQL
  28.     #define SQL_NOUNICODEMAP
  29.     #include <sql.h>        // core
  30. #endif
  31. #ifndef __SQLEXT
  32.     #include <sqlext.h>     // extensions
  33. #endif
  34.  
  35. #ifdef _AFX_MINREBUILD
  36. #pragma component(minrebuild, off)
  37. #endif
  38. #ifndef _AFX_FULLTYPEINFO
  39. #pragma component(mintypeinfo, on)
  40. #endif
  41.  
  42. #ifndef _AFX_NOFORCE_LIBS
  43.  
  44. /////////////////////////////////////////////////////////////////////////////
  45. // Win32 libraries
  46.  
  47. #ifdef _AFXDLL
  48.     #if defined(_DEBUG) && !defined(_AFX_MONOLITHIC)
  49.         #ifndef _UNICODE
  50.             #pragma comment(lib, "mfcd42d.lib")
  51.         #else
  52.             #pragma comment(lib, "mfcd42ud.lib")
  53.         #endif
  54.     #endif
  55. #endif
  56.  
  57. #pragma comment(lib, "odbc32.lib")
  58. #pragma comment(lib, "odbccp32.lib")
  59.  
  60. #endif //!_AFX_NOFORCE_LIBS
  61.  
  62. /////////////////////////////////////////////////////////////////////////////
  63.  
  64. #ifdef _AFX_PACKING
  65. #pragma pack(push, _AFX_PACKING)
  66. #endif
  67.  
  68. /////////////////////////////////////////////////////////////////////////////
  69. // AFXDB - MFC SQL/ODBC/Database support
  70.  
  71. // Classes declared in this file
  72.  
  73.     //CException
  74.         class CDBException;    // abnormal return value
  75.  
  76.     //CFieldExchange
  77.         class CFieldExchange;       // Recordset Field Exchange
  78.  
  79.     //CObject
  80.         class CDatabase;    // Connecting to databases
  81.         class CRecordset;   // Data result sets
  82.  
  83. //CObject
  84.     //CCmdTarget;
  85.         //CWnd
  86.             //CView
  87.                 //CScrollView
  88.                     //CFormView
  89.                         class CRecordView;     // view records with a form
  90.  
  91. // Non CObject classes
  92. class CDBVariant;
  93. struct CRecordsetStatus;
  94. struct CFieldInfo;
  95. struct CODBCFieldInfo;
  96. struct CODBCParamInfo;
  97.  
  98. /////////////////////////////////////////////////////////////////////////////
  99.  
  100. // ODBC helpers
  101. // return code left in 'nRetCode'
  102.  
  103. // This MACRO is now out-of-date (kept for backward compatibility)
  104. #define AFX_ODBC_CALL(SQLFunc) \
  105.     do \
  106.     { \
  107.     } while ((nRetCode = (SQLFunc)) == SQL_STILL_EXECUTING)
  108.  
  109. // Not really required, but kept for compatibilty
  110. #define AFX_SQL_SYNC(SQLFunc) \
  111.     do \
  112.     { \
  113.         nRetCode = SQLFunc; \
  114.     } while (0)
  115.  
  116. // Now out-of-date (prs not used) but kept for compatibility
  117. #define AFX_SQL_ASYNC(prs, SQLFunc) AFX_ODBC_CALL(SQLFunc)
  118.  
  119. // Max display length in chars of timestamp (date & time) value
  120. #define TIMESTAMP_PRECISION 23
  121.  
  122. // AFXDLL support
  123. #undef AFX_DATA
  124. #define AFX_DATA AFX_DB_DATA
  125.  
  126. //  Miscellaneous sizing info
  127. #define MAX_CURRENCY     30     // Max size of Currency($) string
  128. #define MAX_TNAME_LEN    64     // Max size of table names
  129. #define MAX_FNAME_LEN    256    // Max size of field names
  130. #define MAX_DBNAME_LEN   32     // Max size of a database name
  131. #define MAX_DNAME_LEN    256        // Max size of Recordset names
  132. #define MAX_CONNECT_LEN  512        // Max size of Connect string
  133. #define MAX_CURSOR_NAME  18     // Max size of a cursor name
  134. #define DEFAULT_FIELD_TYPE SQL_TYPE_NULL // pick "C" data type to match SQL data type
  135.  
  136. // Timeout and net wait defaults
  137. #define DEFAULT_LOGIN_TIMEOUT 15    // seconds to before fail on connect
  138. #define DEFAULT_QUERY_TIMEOUT 15    // seconds to before fail waiting for results
  139.  
  140. // Field Flags, used to indicate status of fields
  141. #define AFX_SQL_FIELD_FLAG_DIRTY    0x1
  142. #define AFX_SQL_FIELD_FLAG_NULL     0x2
  143.  
  144. // Update options flags
  145. #define AFX_SQL_SETPOSUPDATES       0x0001
  146. #define AFX_SQL_POSITIONEDSQL       0x0002
  147. #define AFX_SQL_GDBOUND             0x0004
  148.  
  149. /////////////////////////////////////////////////////////////////////////////
  150. // CDBException - something gone wrong
  151.  
  152. // Dbkit extended error codes
  153. #define AFX_SQL_ERROR                           1000
  154. #define AFX_SQL_ERROR_CONNECT_FAIL              AFX_SQL_ERROR+1
  155. #define AFX_SQL_ERROR_RECORDSET_FORWARD_ONLY    AFX_SQL_ERROR+2
  156. #define AFX_SQL_ERROR_EMPTY_COLUMN_LIST         AFX_SQL_ERROR+3
  157. #define AFX_SQL_ERROR_FIELD_SCHEMA_MISMATCH     AFX_SQL_ERROR+4
  158. #define AFX_SQL_ERROR_ILLEGAL_MODE              AFX_SQL_ERROR+5
  159. #define AFX_SQL_ERROR_MULTIPLE_ROWS_AFFECTED    AFX_SQL_ERROR+6
  160. #define AFX_SQL_ERROR_NO_CURRENT_RECORD         AFX_SQL_ERROR+7
  161. #define AFX_SQL_ERROR_NO_ROWS_AFFECTED          AFX_SQL_ERROR+8
  162. #define AFX_SQL_ERROR_RECORDSET_READONLY        AFX_SQL_ERROR+9
  163. #define AFX_SQL_ERROR_SQL_NO_TOTAL              AFX_SQL_ERROR+10
  164. #define AFX_SQL_ERROR_ODBC_LOAD_FAILED          AFX_SQL_ERROR+11
  165. #define AFX_SQL_ERROR_DYNASET_NOT_SUPPORTED     AFX_SQL_ERROR+12
  166. #define AFX_SQL_ERROR_SNAPSHOT_NOT_SUPPORTED    AFX_SQL_ERROR+13
  167. #define AFX_SQL_ERROR_API_CONFORMANCE           AFX_SQL_ERROR+14
  168. #define AFX_SQL_ERROR_SQL_CONFORMANCE           AFX_SQL_ERROR+15
  169. #define AFX_SQL_ERROR_NO_DATA_FOUND             AFX_SQL_ERROR+16
  170. #define AFX_SQL_ERROR_ROW_UPDATE_NOT_SUPPORTED  AFX_SQL_ERROR+17
  171. #define AFX_SQL_ERROR_ODBC_V2_REQUIRED          AFX_SQL_ERROR+18
  172. #define AFX_SQL_ERROR_NO_POSITIONED_UPDATES     AFX_SQL_ERROR+19
  173. #define AFX_SQL_ERROR_LOCK_MODE_NOT_SUPPORTED   AFX_SQL_ERROR+20
  174. #define AFX_SQL_ERROR_DATA_TRUNCATED            AFX_SQL_ERROR+21
  175. #define AFX_SQL_ERROR_ROW_FETCH                 AFX_SQL_ERROR+22
  176. #define AFX_SQL_ERROR_INCORRECT_ODBC            AFX_SQL_ERROR+23
  177. #define AFX_SQL_ERROR_UPDATE_DELETE_FAILED      AFX_SQL_ERROR+24
  178. #define AFX_SQL_ERROR_DYNAMIC_CURSOR_NOT_SUPPORTED  AFX_SQL_ERROR+25
  179. #define AFX_SQL_ERROR_FIELD_NOT_FOUND           AFX_SQL_ERROR+26
  180. #define AFX_SQL_ERROR_BOOKMARKS_NOT_SUPPORTED   AFX_SQL_ERROR+27
  181. #define AFX_SQL_ERROR_BOOKMARKS_NOT_ENABLED     AFX_SQL_ERROR+28
  182. #define AFX_SQL_ERROR_MAX                       AFX_SQL_ERROR+29
  183.  
  184. class CDBException : public CException
  185. {
  186.     DECLARE_DYNAMIC(CDBException)
  187.  
  188. // Attributes
  189. public:
  190.     RETCODE m_nRetCode;
  191.     CString m_strError;
  192.     CString m_strStateNativeOrigin;
  193.  
  194. // Implementation (use AfxThrowDBException to create)
  195. public:
  196.     CDBException(RETCODE nRetCode = SQL_SUCCESS);
  197.  
  198.     virtual void BuildErrorString(CDatabase* pdb, HSTMT hstmt,
  199.         BOOL bTrace = TRUE);
  200.     void Empty();
  201.     virtual ~CDBException();
  202.  
  203.     virtual BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
  204.         PUINT pnHelpContext = NULL);
  205.  
  206. #ifdef _DEBUG
  207.     void TraceErrorMessage(LPCTSTR szTrace) const;
  208. #endif // DEBUG
  209.  
  210. };
  211.  
  212. void AFXAPI AfxThrowDBException(RETCODE nRetCode, CDatabase* pdb, HSTMT hstmt);
  213.  
  214. //////////////////////////////////////////////////////////////////////////////
  215. // CDatabase - a SQL Database
  216.  
  217. class CDatabase : public CObject
  218. {
  219.     DECLARE_DYNAMIC(CDatabase)
  220.  
  221. // Constructors
  222. public:
  223.     CDatabase();
  224.  
  225.     enum DbOpenOptions
  226.     {
  227.         openExclusive =         0x0001, // Not implemented
  228.         openReadOnly =          0x0002, // Open database read only
  229.         useCursorLib =          0x0004, // Use ODBC cursor lib
  230.         noOdbcDialog =          0x0008, // Don't display ODBC Connect dialog
  231.         forceOdbcDialog =       0x0010, // Always display ODBC connect dialog
  232.     };
  233.  
  234.     virtual BOOL Open(LPCTSTR lpszDSN, BOOL bExclusive = FALSE,
  235.         BOOL bReadonly = FALSE, LPCTSTR lpszConnect = _T("ODBC;"),
  236.         BOOL bUseCursorLib = TRUE);
  237.     virtual BOOL OpenEx(LPCTSTR lpszConnectString, DWORD dwOptions = 0);
  238.     virtual void Close();
  239.  
  240. // Attributes
  241. public:
  242.     HDBC m_hdbc;
  243.  
  244.     BOOL IsOpen() const;        // Database successfully opened?
  245.     BOOL CanUpdate() const;
  246.     BOOL CanTransact() const;   // Are Transactions supported?
  247.  
  248.     CString GetDatabaseName() const;
  249.     const CString& GetConnect() const;
  250.  
  251.     DWORD GetBookmarkPersistence() const;
  252.     int GetCursorCommitBehavior() const;
  253.     int GetCursorRollbackBehavior() const;
  254.  
  255. // Operations
  256. public:
  257.     void SetLoginTimeout(DWORD dwSeconds);
  258.     void SetQueryTimeout(DWORD dwSeconds);
  259.  
  260.     // transaction control
  261.     BOOL BeginTrans();
  262.     BOOL CommitTrans();
  263.     BOOL Rollback();
  264.  
  265.     void ExecuteSQL(LPCTSTR lpszSQL);
  266.  
  267.     // Cancel asynchronous operation
  268.     void Cancel();
  269.  
  270. // Overridables
  271. public:
  272.     // set special options
  273.     virtual void OnSetOptions(HSTMT hstmt);
  274.  
  275. // Implementation
  276. public:
  277.     virtual ~CDatabase();
  278.  
  279. #ifdef _DEBUG
  280.     virtual void AssertValid() const;
  281.     virtual void Dump(CDumpContext& dc) const;
  282.  
  283.     BOOL m_bTransactionPending;
  284. #endif //_DEBUG
  285.  
  286.     // general error check
  287.     virtual BOOL Check(RETCODE nRetCode) const;
  288.     BOOL PASCAL CheckHstmt(RETCODE, HSTMT hstmt) const;
  289.  
  290.     // Note: CDatabase::BindParameters is now documented and is no longer
  291.     //  officially 'implementation.'  Feel free to use it.  It stays here
  292.     //  because moving it would break binary compatibility.
  293.     virtual void BindParameters(HSTMT hstmt);
  294.  
  295.     void ReplaceBrackets(LPTSTR lpchSQL);
  296.     BOOL m_bStripTrailingSpaces;
  297.     BOOL m_bIncRecordCountOnAdd;
  298.     BOOL m_bAddForUpdate;
  299.     char m_chIDQuoteChar;
  300.     char m_reserved1[3];        // pad to even 4 bytes
  301.  
  302.     void SetSynchronousMode(BOOL bSynchronous); // Obsolete, doe nothing
  303.  
  304. protected:
  305.     CString m_strConnect;
  306.  
  307.     CPtrList m_listRecordsets;  // maintain list to ensure CRecordsets all closed
  308.  
  309.     int nRefCount;
  310.     BOOL m_bUpdatable;
  311.  
  312.     BOOL m_bTransactions;
  313.     SWORD m_nTransactionCapable;
  314.     SWORD m_nCursorCommitBehavior;
  315.     SWORD m_nCursorRollbackBehavior;
  316.     DWORD m_dwUpdateOptions;
  317.     DWORD m_dwBookmarkAttributes;   // cache driver bookmark persistence
  318.  
  319.     DWORD m_dwLoginTimeout;
  320.     HSTMT m_hstmt;
  321.  
  322.     DWORD m_dwQueryTimeout;
  323.  
  324.     virtual void ThrowDBException(RETCODE nRetCode);
  325.     void AllocConnect(DWORD dwOptions);
  326.     BOOL Connect(DWORD dwOptions);
  327.     void VerifyConnect();
  328.     void GetConnectInfo();
  329.     void Free();
  330.  
  331.     // friend classes that call protected CDatabase overridables
  332.     friend class CRecordset;
  333.     friend class CFieldExchange;
  334.     friend class CDBException;
  335. };
  336.  
  337. //////////////////////////////////////////////////////////////////////////////
  338. // CFieldExchange - for field exchange
  339. class CFieldExchange
  340. {
  341. // Attributes
  342. public:
  343.     enum RFX_Operation
  344.     {
  345.         BindParam,          // register users parameters with ODBC SQLBindParameter
  346.         RebindParam,        //  migrate param values to proxy array before Requery
  347.         BindFieldToColumn,  // register users fields with ODBC SQLBindCol
  348.         BindFieldForUpdate, // temporarily bind columns before update (via SQLSetPos)
  349.         UnbindFieldForUpdate,   // unbind columns after update (via SQLSetPos)
  350.         Fixup,              // Set string lengths, clear status bits
  351.         MarkForAddNew,      // Prepare fields and flags for addnew operation
  352.         MarkForUpdate,      // Prepare fields and flags for update operation
  353.         Name,               // append dirty field name
  354.         NameValue,          // append dirty name=value
  355.         Value,              // append dirty value or parameter marker
  356.         SetFieldNull,       // Set status bit for null value
  357.         StoreField,         // archive values of current record
  358.         LoadField,          // reload archived values into current record
  359.         AllocCache,         // allocate cache used for dirty field check
  360.         AllocMultiRowBuffer,    // allocate buffer holding multi rows of data
  361.         DeleteMultiRowBuffer,   // delete buffer holding multi rows of data
  362. #ifdef _DEBUG
  363.         DumpField,          // dump bound field name and value
  364. #endif
  365.     };
  366.     UINT m_nOperation;  // Type of exchange operation
  367.     CRecordset* m_prs;  // recordset handle
  368.  
  369. // Operations
  370.     enum FieldType
  371.     {
  372.         noFieldType     = -1,
  373.         outputColumn    = 0,
  374.         param           = SQL_PARAM_INPUT,
  375.         inputParam      = param,
  376.         outputParam     = SQL_PARAM_OUTPUT,
  377.         inoutParam      = SQL_PARAM_INPUT_OUTPUT,
  378.     };
  379.  
  380. // Operations (for implementors of RFX procs)
  381.     BOOL IsFieldType(UINT* pnField);
  382.  
  383.     // Indicate purpose of subsequent RFX calls
  384.     void SetFieldType(UINT nFieldType);
  385.  
  386. // Implementation
  387.     CFieldExchange(UINT nOperation, CRecordset* prs, void* pvField = NULL);
  388.  
  389.     void Default(LPCTSTR szName,
  390.         void* pv, LONG* plLength, int nCType, UINT cbValue, UINT cbPrecision);
  391.  
  392.     // long binary helpers
  393.     long GetLongBinarySize(int nField);
  394.     void GetLongBinaryData(int nField, CLongBinary& lb, long* plSize);
  395.     BYTE* ReallocLongBinary(CLongBinary& lb, long lSizeRequired,
  396.         long lReallocSize);
  397.  
  398.     // Current type of field
  399.     UINT m_nFieldType;
  400.  
  401.     UINT m_nFieldFound;
  402.  
  403.     CString* m_pstr;    // Field name or destination for building various SQL clauses
  404.     BOOL m_bField;      // Value to set for SetField operation
  405.     void* m_pvField;    // For indicating an operation on a specific field
  406.     LPCTSTR m_lpszSeparator; // append after field names
  407.     UINT m_nFields;     // count of fields for various operations
  408.     UINT m_nParams;     // count of fields for various operations
  409.     UINT m_nParamFields;    // count of fields for various operations
  410.     HSTMT m_hstmt;      // For SQLBindParameter on update statement
  411.     long m_lDefaultLBFetchSize;     // For fetching CLongBinary data of unknown len
  412.     long m_lDefaultLBReallocSize;   // For fetching CLongBinary data of unknown len
  413.  
  414. #ifdef _DEBUG
  415.     CDumpContext* m_pdcDump;
  416. #endif //_DEBUG
  417.  
  418. };
  419.  
  420. /////////////////////////////////////////////////////////////////////////////
  421. // Global helper
  422.  
  423. HENV AFXAPI AfxGetHENV();
  424.  
  425. /////////////////////////////////////////////////////////////////////////////
  426. // Recordset Field Exchange helpers
  427.  
  428. void AFXAPI AfxStoreField(CRecordset& rs, UINT nField, void* pvField);
  429. void AFXAPI AfxLoadField(CRecordset& rs, UINT nField,
  430.     void* pvField, long* plLength);
  431. BOOL AFXAPI AfxCompareValueByRef(void* pvData, void* pvCache, int nDataType);
  432. void AFXAPI AfxCopyValueByRef(void* pvCache, void* pvData,
  433.     long* plLength, int nDataType);
  434.  
  435. /////////////////////////////////////////////////////////////////////////////
  436. // Standard Recordset Field Exchange routines
  437.  
  438. // text data
  439. void AFXAPI RFX_Text(CFieldExchange* pFX, LPCTSTR szName, CString& value,
  440.     // Default max length for char and varchar, default datasource type
  441.     int nMaxLength = 255, int nColumnType = SQL_VARCHAR, short nScale = 0);
  442.  
  443. void AFXAPI RFX_Text(CFieldExchange* pFX, LPCTSTR szName, LPTSTR value,
  444.     int nMaxLength, int nColumnType = SQL_VARCHAR, short nScale = 0);
  445.  
  446. // boolean data
  447. void AFXAPI RFX_Bool(CFieldExchange* pFX, LPCTSTR szName, BOOL& value);
  448.  
  449. // integer data
  450. void AFXAPI RFX_Long(CFieldExchange* pFX, LPCTSTR szName, long& value);
  451. void AFXAPI RFX_Int(CFieldExchange* pFX, LPCTSTR szName, int& value);
  452. void AFXAPI RFX_Single(CFieldExchange* pFX, LPCTSTR szName, float& value);
  453. void AFXAPI RFX_Double(CFieldExchange* pFX, LPCTSTR szName, double& value);
  454.  
  455. // date and time
  456. void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, CTime& value);
  457. void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, TIMESTAMP_STRUCT& value);
  458. void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, COleDateTime& value);
  459.  
  460. // Binary data
  461. void AFXAPI RFX_Binary(CFieldExchange* pFX, LPCTSTR szName, CByteArray& value,
  462.     // Default max length is for binary and varbinary
  463.     int nMaxLength = 255);
  464. void AFXAPI RFX_Byte(CFieldExchange* pFX, LPCTSTR szName, BYTE& value);
  465. void AFXAPI RFX_LongBinary(CFieldExchange* pFX, LPCTSTR szName, CLongBinary& value);
  466.  
  467. /////////////////////////////////////////////////////////////////////////////
  468. // Bulk Recordset Field Exchange helpers
  469. void AFXAPI AfxRFXBulkDefault(CFieldExchange* pFX, LPCTSTR szName,
  470.     void* pv, long* rgLengths, int nCType, UINT cbValue);
  471.  
  472. /////////////////////////////////////////////////////////////////////////////
  473. // Bulk Recordset Field Exchange routines
  474.  
  475. void AFXAPI RFX_Text_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  476.     LPSTR* prgStrVals, long** prgLengths, int nMaxLength);
  477.  
  478. void AFXAPI RFX_Bool_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  479.     BOOL** prgBoolVals, long** prgLengths);
  480. void AFXAPI RFX_Int_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  481.     int** prgIntVals, long** prgLengths);
  482. void AFXAPI RFX_Long_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  483.     long** prgLongVals, long** prgLengths);
  484.  
  485. void AFXAPI RFX_Single_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  486.     float** prgFltVals, long** prgLengths);
  487. void AFXAPI RFX_Double_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  488.     double** prgDblVals, long** prgLengths);
  489.  
  490. void AFXAPI RFX_Date_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  491.     TIMESTAMP_STRUCT** prgTSVals, long** prgLengths);
  492.  
  493. void AFXAPI RFX_Byte_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  494.     BYTE** prgByteVals, long** prgLengths);
  495. void AFXAPI RFX_Binary_Bulk(CFieldExchange* pFX, LPCTSTR szName,
  496.     BYTE** prgByteVals, long** prgLengths, int nMaxLength);
  497.  
  498. /////////////////////////////////////////////////////////////////////////////
  499. // Database Dialog Data Exchange cover routines
  500. // Cover routines provide database semantics on top of DDX routines
  501.  
  502. // simple text operations
  503. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, BYTE& value,
  504.     CRecordset* pRecordset);
  505. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, int& value,
  506.     CRecordset* pRecordset);
  507. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, UINT& value,
  508.     CRecordset* pRecordset);
  509. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, long& value,
  510.     CRecordset* pRecordset);
  511. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, DWORD& value,
  512.     CRecordset* pRecordset);
  513. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, CString& value,
  514.     CRecordset* pRecordset);
  515. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, LPTSTR pstrValue,
  516.     int nMaxLen, CRecordset* pRecordset);
  517. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, double& value,
  518.     CRecordset* pRecordset);
  519. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, float& value,
  520.     CRecordset* pRecordset);
  521. void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, CTime& value,
  522.     CRecordset* pRecordset);
  523.  
  524. // special control types
  525. void AFXAPI DDX_FieldCheck(CDataExchange* pDX, int nIDC, int& value,
  526.     CRecordset* pRecordset);
  527. void AFXAPI DDX_FieldRadio(CDataExchange* pDX, int nIDC, int& value,
  528.     CRecordset* pRecordset);
  529. void AFXAPI DDX_FieldLBString(CDataExchange* pDX, int nIDC,
  530.     CString& value,
  531.     CRecordset* pRecordset);
  532. void AFXAPI DDX_FieldCBString(CDataExchange* pDX, int nIDC,
  533.     CString& value,
  534.     CRecordset* pRecordset);
  535. void AFXAPI DDX_FieldLBIndex(CDataExchange* pDX, int nIDC, int& index,
  536.     CRecordset* pRecordset);
  537. void AFXAPI DDX_FieldCBIndex(CDataExchange* pDX, int nIDC, int& index,
  538.     CRecordset* pRecordset);
  539. void AFXAPI DDX_FieldLBStringExact(CDataExchange* pDX, int nIDC,
  540.     CString& value,
  541.     CRecordset* pRecordset);
  542. void AFXAPI DDX_FieldCBStringExact(CDataExchange* pDX, int nIDC,
  543.     CString& value,
  544.     CRecordset* pRecordset);
  545. void AFXAPI DDX_FieldScroll(CDataExchange* pDX, int nIDC, int& value,
  546.     CRecordset* pRecordset);
  547.  
  548. //////////////////////////////////////////////////////////////////////////////
  549. // CRecordset - the result of a SQL Statement
  550.  
  551. #define AFX_DB_USE_DEFAULT_TYPE     (0xFFFFFFFF)
  552.  
  553. // Most Move constants out of date
  554. // #define AFX_MOVE_FIRST      0x80000000L
  555. // #define AFX_MOVE_PREVIOUS   (-1L)
  556. #define AFX_MOVE_REFRESH    0L
  557. // #define AFX_MOVE_NEXT       (+1L)
  558. // #define AFX_MOVE_LAST       0x7fffffffL
  559.  
  560. #define AFX_RECORDSET_STATUS_OPEN    (+1L)
  561. #define AFX_RECORDSET_STATUS_CLOSED  0L
  562. #define AFX_RECORDSET_STATUS_UNKNOWN (-1L)
  563.  
  564. class CRecordset : public CObject
  565. {
  566.     DECLARE_DYNAMIC(CRecordset)
  567.  
  568. // Constructor
  569. public:
  570.     CRecordset(CDatabase* pDatabase = NULL);
  571.  
  572. public:
  573.     virtual ~CRecordset();
  574.  
  575.     enum OpenType
  576.     {
  577.         dynaset,        // uses SQLExtendedFetch, keyset driven cursor
  578.         snapshot,       // uses SQLExtendedFetch, static cursor
  579.         forwardOnly,    // uses SQLFetch
  580.         dynamic         // uses SQLExtendedFetch, dynamic cursor
  581.     };
  582.  
  583.     enum OpenOptions
  584.     {
  585.         none =                      0x0,
  586.         readOnly =                  0x0004,
  587.         appendOnly =                0x0008,
  588.         skipDeletedRecords =        0x0010, // turn on skipping of deleted records, Will slow Move(n).
  589.         noDirtyFieldCheck =         0x0020, // disable automatic dirty field checking
  590.         useBookmarks =              0x0100, // turn on bookmark support
  591.         useMultiRowFetch =          0x0200, // turn on multi-row fetch model
  592.         userAllocMultiRowBuffers =  0x0400, // if multi-row fetch on, user will alloc memory for buffers
  593.         useExtendedFetch =          0x0800, // use SQLExtendedFetch with forwardOnly type recordsets
  594.         executeDirect =             0x2000, // Directly execute SQL rather than prepared execute
  595.         optimizeBulkAdd =           0x4000, // Use prepared HSTMT for multiple AddNews, dirty fields must not change.
  596.         firstBulkAdd =              0x8000, // INTERNAL to MFC, don't specify on Open.
  597.     };
  598.     virtual BOOL Open(UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE,
  599.         LPCTSTR lpszSQL = NULL, DWORD dwOptions = none);
  600.     virtual void Close();
  601.  
  602. // Attributes
  603. public:
  604.     HSTMT m_hstmt;          // Source statement for this resultset
  605.     CDatabase* m_pDatabase;       // Source database for this resultset
  606.  
  607.     CString m_strFilter;        // Where clause
  608.     CString m_strSort;      // Order By Clause
  609.  
  610.     BOOL CanAppend() const;     // Can AddNew be called?
  611.     BOOL CanRestart() const;    // Can Requery be called to restart a query?
  612.     BOOL CanScroll() const;     // Can MovePrev and MoveFirst be called?
  613.     BOOL CanTransact() const;   // Are Transactions supported?
  614.     BOOL CanUpdate() const;     // Can Edit/AddNew/Delete be called?
  615.     BOOL CanBookmark() const;       // Can Get/SetBookmark be called?
  616.  
  617.     const CString& GetSQL() const;      // SQL executed for this recordset
  618.     const CString& GetTableName() const;        // Table name
  619.  
  620.     BOOL IsOpen() const;        // Recordset successfully opened?
  621.     BOOL IsBOF() const;     // Beginning Of File
  622.     BOOL IsEOF() const;     // End Of File
  623.     BOOL IsDeleted() const;     // On a deleted record
  624.  
  625.     BOOL IsFieldDirty(void *pv);    // has field been updated?
  626.     BOOL IsFieldNull(void *pv); // is field NULL valued?
  627.     BOOL IsFieldNullable(void *pv); // can field be set to a NULL value
  628.  
  629.     long GetRecordCount() const;        // Records seen so far or -1 if unknown
  630.     void GetStatus(CRecordsetStatus& rStatus) const;
  631.  
  632. // Operations
  633. public:
  634.     // cursor operations
  635.     void MoveNext();
  636.     void MovePrev();
  637.     void MoveFirst();
  638.     void MoveLast();
  639.     virtual void Move(long nRows, WORD wFetchType = SQL_FETCH_RELATIVE);
  640.  
  641.     void SetAbsolutePosition(long nRows);
  642.  
  643.     void GetBookmark(CDBVariant& varBookmark);
  644.     void SetBookmark(const CDBVariant& varBookmark);
  645.  
  646.     virtual void SetRowsetSize(DWORD dwNewRowsetSize);
  647.     DWORD GetRowsetSize() const;
  648.     DWORD GetRowsFetched() const;
  649.     virtual void CheckRowsetError(RETCODE nRetCode);
  650.     void RefreshRowset(WORD wRow, WORD wLockType = SQL_LOCK_NO_CHANGE);
  651.     void SetRowsetCursorPosition(WORD wRow, WORD wLockType = SQL_LOCK_NO_CHANGE);
  652.     WORD GetRowStatus(WORD wRow) const;
  653.  
  654.     // edit buffer operations
  655.     virtual void AddNew();      // add new record at the end
  656.     virtual void Edit();        // start editing
  657.     virtual BOOL Update();      // update it
  658.     virtual void Delete();      // delete the current record
  659.     void CancelUpdate();        // cancel pending Edit/AddNew
  660.  
  661.     BOOL FlushResultSet() const;
  662.  
  663.     // field operations
  664.     short GetODBCFieldCount() const;
  665.     void GetODBCFieldInfo(short nIndex, CODBCFieldInfo& fieldinfo);
  666.     void GetODBCFieldInfo(LPCTSTR lpszName, CODBCFieldInfo& fieldinfo);
  667.     void GetFieldValue(LPCTSTR lpszName, CDBVariant& varValue,
  668.         short nFieldType = DEFAULT_FIELD_TYPE);
  669.     void GetFieldValue(short nIndex, CDBVariant& varValue,
  670.         short nFieldType = DEFAULT_FIELD_TYPE);
  671.     void GetFieldValue(LPCTSTR lpszName, CString& strValue);
  672.     void GetFieldValue(short nIndex, CString& strValue);
  673.  
  674.     void SetFieldDirty(void *pv, BOOL bDirty = TRUE);
  675.     void SetFieldNull(void *pv, BOOL bNull = TRUE);
  676.     void SetParamNull(int nIndex, BOOL bNull = TRUE);
  677.  
  678.     // locking control during Edit
  679.     enum LockMode
  680.     {
  681.         optimistic,
  682.         pessimistic,
  683.     };
  684.     void SetLockingMode(UINT nMode);
  685.  
  686.     // Recordset operations
  687.     virtual BOOL Requery();         // Re-execute query based on new params
  688.  
  689.     // Cancel asynchronous operation
  690.     void Cancel();
  691.  
  692. // Overridables
  693. public:
  694.     // Get default connect string
  695.     virtual CString GetDefaultConnect();
  696.  
  697.     // Get SQL to execute
  698.     virtual CString GetDefaultSQL();
  699.  
  700.     // set special options
  701.     virtual void OnSetOptions(HSTMT hstmt);
  702.  
  703.     // for recordset field exchange
  704.     virtual void DoFieldExchange(CFieldExchange* pFX);
  705.     virtual void DoBulkFieldExchange(CFieldExchange* pFX);
  706.  
  707. // Implementation
  708. public:
  709. #ifdef _DEBUG
  710.     virtual void AssertValid() const;
  711.     virtual void Dump(CDumpContext& dc) const;
  712. #endif //_DEBUG
  713.  
  714.     virtual BOOL Check(RETCODE nRetCode) const; // general error check
  715.  
  716.     void InitRecord();
  717.     void ResetCursor();
  718.     void CheckRowsetCurrencyStatus(UWORD wFetchType, long nRows);
  719.     RETCODE FetchData(UWORD wFetchType, SDWORD nRow,
  720.         DWORD* pdwRowsFetched);
  721.     void SkipDeletedRecords(UWORD wFetchType, long nRows,
  722.         DWORD* pdwRowsFetched, RETCODE* pnRetCode);
  723.     virtual void SetRowsetCurrencyStatus(RETCODE nRetCode,
  724.         UWORD wFetchType, long nRows, DWORD dwRowsFetched);
  725.  
  726.     virtual void PreBindFields();   // called before data fields are bound
  727.     UINT m_nFields;         // number of RFX fields
  728.     UINT m_nParams;         // number of RFX params
  729.     BOOL m_bCheckCacheForDirtyFields;   // switch for dirty field checking
  730.     BOOL m_bRebindParams;     // date or UNICODE text parameter existence flag
  731.     BOOL m_bLongBinaryColumns;  // long binary column existence flag
  732.     BOOL m_bUseUpdateSQL;   // uses SQL-based updates
  733.     DWORD m_dwOptions;          // archive dwOptions on Open
  734.     SWORD m_nResultCols;    // number of columns in result set
  735.     BOOL m_bUseODBCCursorLib;   // uses ODBC cursor lib if m_pDatabase not Open
  736.     CODBCFieldInfo* m_rgODBCFieldInfos; // Array of field info structs with ODBC meta-data
  737.     CFieldInfo* m_rgFieldInfos;         // Array of field info structs with MFC specific field data
  738.     CMapPtrToPtr m_mapFieldIndex;       // Map of member address to field index
  739.     CMapPtrToPtr m_mapParamIndex;       // Map of member address to field index
  740.  
  741.     BOOL IsSQLUpdatable(LPCTSTR lpszSQL);
  742.     BOOL IsSelectQueryUpdatable(LPCTSTR lpszSQL);
  743.     static BOOL PASCAL IsJoin(LPCTSTR lpszJoinClause);
  744.     static LPCTSTR PASCAL FindSQLToken(LPCTSTR lpszSQL, LPCTSTR lpszSQLToken);
  745.  
  746.     // RFX Operations on fields of CRecordset
  747.     UINT BindParams(HSTMT hstmt);
  748.     void RebindParams(HSTMT hstmt);
  749.     UINT BindFieldsToColumns();
  750.     void BindFieldsForUpdate();
  751.     void UnbindFieldsForUpdate();
  752.     void Fixups();
  753.     UINT AppendNames(CString* pstr, LPCTSTR szSeparator);
  754.     UINT AppendValues(HSTMT hstmt, CString* pstr, LPCTSTR szSeparator);
  755.     UINT AppendNamesValues(HSTMT hstmt, CString* pstr, LPCTSTR szSeparator);
  756.     void StoreFields();
  757.     void LoadFields();
  758.     void MarkForAddNew();
  759.     void MarkForUpdate();
  760.     void AllocDataCache();
  761.     void FreeDataCache();
  762. #ifdef _DEBUG
  763.     void DumpFields(CDumpContext& dc) const;
  764. #endif //_DEBUG
  765.  
  766.     // RFX operation helper functions
  767.     virtual void ThrowDBException(RETCODE nRetCode, HSTMT hstmt = SQL_NULL_HSTMT);
  768.  
  769.     int GetBoundFieldIndex(void* pv);
  770.     int GetBoundParamIndex(void* pv);
  771.     short GetFieldIndexByName(LPCTSTR lpszFieldName);
  772.  
  773.     void AllocStatusArrays();
  774.     long* GetFieldLengthBuffer(DWORD nField, int nFieldType);   // for fields & params
  775.  
  776.     BYTE GetFieldStatus(DWORD nField);
  777.     void SetFieldStatus(DWORD nField, BYTE bFlags);
  778.     void ClearFieldStatus();
  779.  
  780.     BOOL IsFieldStatusDirty(DWORD nField) const;
  781.     void SetDirtyFieldStatus(DWORD nField);
  782.     void ClearDirtyFieldStatus(DWORD nField);
  783.  
  784.     BOOL IsFieldStatusNull(DWORD nField) const;
  785.     void SetNullFieldStatus(DWORD nField);
  786.     void ClearNullFieldStatus(DWORD nField);
  787.  
  788.     BOOL IsParamStatusNull(DWORD nField) const;
  789.     void SetNullParamStatus(DWORD nField);
  790.     void ClearNullParamStatus(DWORD nField);
  791.  
  792.     BOOL IsFieldNullable(DWORD nField) const;
  793.  
  794.     void** m_pvFieldProxy;
  795.     void** m_pvParamProxy;
  796.     UINT m_nProxyFields;
  797.     UINT m_nProxyParams;
  798.  
  799.     // GetFieldValue helpers
  800.     static short PASCAL GetDefaultFieldType(short nSQLType);
  801.     static void* PASCAL GetDataBuffer(CDBVariant& varValue, short nFieldType,
  802.         int* pnLen, short nSQLType, UDWORD nPrecision);
  803.     static int PASCAL GetTextLen(short nSQLType, UDWORD nPrecision);
  804.     static long PASCAL GetData(CDatabase* pdb, HSTMT hstmt, short nFieldIndex,
  805.         short nFieldType, LPVOID pvData, int nLen, short nSQLType);
  806.     static void PASCAL GetLongBinaryDataAndCleanup(CDatabase* pdb, HSTMT hstmt,
  807.         short nFieldIndex, long nActualSize, LPVOID* ppvData, int nLen,
  808.         CDBVariant& varValue, short nSQLType);
  809.     static void PASCAL GetLongCharDataAndCleanup(CDatabase* pdb, HSTMT hstmt,
  810.         short nFieldIndex, long nActualSize, LPVOID* ppvData, int nLen,
  811.         CString& strValue, short nSQLType);
  812.  
  813. protected:
  814.     UINT m_nOpenType;
  815.     UINT m_nDefaultType;
  816.     enum EditMode
  817.     {
  818.         noMode,
  819.         edit,
  820.         addnew
  821.     };
  822.     long m_lOpen;
  823.     UINT m_nEditMode;
  824.     BOOL m_bEOFSeen;
  825.     long m_lRecordCount;
  826.     long m_lCurrentRecord;
  827.     CString m_strCursorName;
  828.     // Perform operation based on m_nEditMode
  829.     BOOL UpdateInsertDelete();
  830.     BOOL m_nLockMode;       // Control concurrency for Edit()
  831.     UDWORD m_dwDriverConcurrency;   // driver supported concurrency types
  832.     UDWORD m_dwConcurrency; // requested concurrency type
  833.     UWORD* m_rgRowStatus;     // row status used by SQLExtendedFetch and SQLSetPos
  834.     DWORD m_dwRowsFetched;  // number of rows fetched by SQLExtendedFetch
  835.     HSTMT m_hstmtUpdate;
  836.     BOOL m_bRecordsetDb;
  837.     BOOL m_bBOF;
  838.     BOOL m_bEOF;
  839.     BOOL m_bUpdatable;      // Is recordset updatable?
  840.     BOOL m_bAppendable;
  841.     CString m_strSQL;       // SQL statement for recordset
  842.     CString m_strUpdateSQL; // SQL statement for updates
  843.     CString m_strTableName;     // source table of recordset
  844.     BOOL m_bScrollable; // supports MovePrev
  845.     BOOL m_bDeleted;
  846.     int m_nFieldsBound;
  847.     BYTE* m_pbFieldFlags;
  848.     BYTE* m_pbParamFlags;
  849.     LONG* m_plParamLength;
  850.     DWORD m_dwInitialGetDataLen;    // Initial GetFieldValue alloc size for long data
  851.     DWORD m_dwRowsetSize;
  852.     DWORD m_dwAllocatedRowsetSize;
  853.  
  854. protected:
  855.     CString m_strRequerySQL;    // archive SQL string for use in Requery()
  856.     CString m_strRequeryFilter; // archive filter string for use in Requery()
  857.     CString m_strRequerySort;   // archive sort string for use in Requery()
  858.  
  859.     void SetState(int nOpenType, LPCTSTR lpszSQL, DWORD dwOptions);
  860.     BOOL AllocHstmt();
  861.     void BuildSQL(LPCTSTR lpszSQL);
  862.     void PrepareAndExecute();
  863.  
  864.     void BuildSelectSQL();
  865.     void AppendFilterAndSortSQL();
  866.     BOOL IsRecordsetUpdatable();
  867.  
  868.     void VerifyDriverBehavior();
  869.     DWORD VerifyCursorSupport();
  870.     void EnableBookmarks();
  871.     void SetUpdateMethod();
  872.     void SetConcurrencyAndCursorType(HSTMT hstmt, DWORD dwScrollOptions);
  873.     void AllocAndCacheFieldInfo();
  874.     void AllocRowset();
  875.     void FreeRowset();
  876.  
  877.     void ExecuteSetPosUpdate();
  878.     void PrepareUpdateHstmt();
  879.     void BuildUpdateSQL();
  880.     void ExecuteUpdateSQL();
  881.     void SendLongBinaryData(HSTMT hstmt);
  882.     virtual long GetLBFetchSize(long lOldSize);     // CLongBinary fetch chunking
  883.     virtual long GetLBReallocSize(long lOldSize);   // CLongBinary realloc chunking
  884.  
  885.     friend class CFieldExchange;
  886.     friend class CRecordView;
  887. };
  888.  
  889. /////////////////////////////////////////////////////////////////////////////
  890. // Info helper definitions
  891. #define AFX_CURRENT_RECORD_UNDEFINED (-2)
  892. #define AFX_CURRENT_RECORD_BOF (-1)
  893.  
  894. // For returning status for a recordset
  895. struct CRecordsetStatus
  896. {
  897.     long m_lCurrentRecord;  // -2=Unknown,-1=BOF,0=1st record. . .
  898.     BOOL m_bRecordCountFinal;// Have we counted all records?
  899. };
  900.  
  901. // Must maintian data binding info
  902. struct CFieldInfo
  903. {
  904.     // MFC specific info
  905.     void* m_pvDataCache;
  906.     long m_nLength;
  907.     int m_nDataType;
  908.     BYTE m_bStatus;
  909. #ifdef _DEBUG
  910.     void* m_pvBindAddress;
  911. #endif
  912. };
  913.  
  914. struct CODBCFieldInfo
  915. {
  916.     // meta data from ODBC
  917.     CString m_strName;
  918.     SWORD m_nSQLType;
  919.     UDWORD m_nPrecision;
  920.     SWORD m_nScale;
  921.     SWORD m_nNullability;
  922. };
  923.  
  924. struct CODBCParamInfo
  925. {
  926.     // meta data from ODBC
  927.     SWORD m_nSQLType;
  928.     UDWORD m_nPrecision;
  929.     SWORD m_nScale;
  930.     SWORD m_nNullability;
  931. };
  932.  
  933.  
  934. /////////////////////////////////////////////////////////////////////////////
  935. // CDBVariant
  936.  
  937. #define DBVT_NULL       0
  938. #define DBVT_BOOL       1
  939. #define DBVT_UCHAR      2
  940. #define DBVT_SHORT      3
  941. #define DBVT_LONG       4
  942. #define DBVT_SINGLE     5
  943. #define DBVT_DOUBLE     6
  944. #define DBVT_DATE       7
  945. #define DBVT_STRING     8
  946. #define DBVT_BINARY     9
  947.  
  948. class CDBVariant
  949. {
  950. // Constructor
  951. public:
  952.     CDBVariant();
  953.  
  954. // Attributes
  955. public:
  956.     DWORD m_dwType;
  957.  
  958.     union
  959.     {
  960.       BOOL              m_boolVal;
  961.       unsigned char     m_chVal;
  962.       short             m_iVal;
  963.       long              m_lVal;
  964.       float             m_fltVal;
  965.       double            m_dblVal;
  966.       TIMESTAMP_STRUCT* m_pdate;
  967.       CString*          m_pstring;
  968.       CLongBinary*      m_pbinary;
  969.     };
  970.  
  971. // Operations
  972.     void Clear();
  973.  
  974. // Implementation
  975. public:
  976.     virtual ~CDBVariant();
  977. };
  978.  
  979. /////////////////////////////////////////////////////////////////////////////
  980. // CRecordView - form for viewing data records
  981.  
  982. #ifdef _AFXDLL
  983. class CRecordView : public CFormView
  984. #else
  985. class AFX_NOVTABLE CRecordView : public CFormView
  986. #endif
  987. {
  988.     DECLARE_DYNAMIC(CRecordView)
  989.  
  990. // Construction
  991. protected:  // must derive your own class
  992.     CRecordView(LPCTSTR lpszTemplateName);
  993.     CRecordView(UINT nIDTemplate);
  994.  
  995. // Attributes
  996. public:
  997.     virtual CRecordset* OnGetRecordset() = 0;
  998.  
  999.     BOOL IsOnLastRecord();
  1000.     BOOL IsOnFirstRecord();
  1001.  
  1002. // Operations
  1003. public:
  1004.     virtual BOOL OnMove(UINT nIDMoveCommand);
  1005.  
  1006. // Implementation
  1007. public:
  1008.     virtual ~CRecordView();
  1009. #ifdef _DEBUG
  1010.     virtual void AssertValid() const;
  1011.     virtual void Dump(CDumpContext& dc) const;
  1012. #endif
  1013.     virtual void OnInitialUpdate();
  1014.  
  1015. protected:
  1016.     BOOL m_bOnFirstRecord;
  1017.     BOOL m_bOnLastRecord;
  1018.  
  1019.     //{{AFX_MSG(CRecordView)
  1020.     afx_msg void OnUpdateRecordFirst(CCmdUI* pCmdUI);
  1021.     afx_msg void OnUpdateRecordPrev(CCmdUI* pCmdUI);
  1022.     afx_msg void OnUpdateRecordNext(CCmdUI* pCmdUI);
  1023.     afx_msg void OnUpdateRecordLast(CCmdUI* pCmdUI);
  1024.     //}}AFX_MSG
  1025.     afx_msg void OnMove(int cx, int cy);
  1026.  
  1027.     DECLARE_MESSAGE_MAP()
  1028. };
  1029.  
  1030. /////////////////////////////////////////////////////////////////////////////
  1031. // Inline function declarations
  1032.  
  1033. #ifdef _AFX_PACKING
  1034. #pragma pack(pop)
  1035. #endif
  1036.  
  1037. #ifdef _AFX_ENABLE_INLINES
  1038. #define _AFXDBCORE_INLINE AFX_INLINE
  1039. #define _AFXDBRFX_INLINE AFX_INLINE
  1040. #define _AFXDBVIEW_INLINE AFX_INLINE
  1041. #include <afxdb.inl>
  1042. #undef _AFXDBVIEW_INLINE
  1043. #undef _AFXDBCORE_INLINE
  1044. #undef _AFXDBRFX_INLINE
  1045. #endif
  1046.  
  1047. #undef AFX_DATA
  1048. #define AFX_DATA
  1049.  
  1050. #ifdef _AFX_MINREBUILD
  1051. #pragma component(minrebuild, on)
  1052. #endif
  1053. #ifndef _AFX_FULLTYPEINFO
  1054. #pragma component(mintypeinfo, off)
  1055. #endif
  1056.  
  1057. #endif //__AFXDB_H__
  1058.  
  1059. /////////////////////////////////////////////////////////////////////////////
  1060.