diff options
Diffstat (limited to '')
-rw-r--r-- | public/sdk/inc/mfc42/afxdb.h | 1042 |
1 files changed, 1042 insertions, 0 deletions
diff --git a/public/sdk/inc/mfc42/afxdb.h b/public/sdk/inc/mfc42/afxdb.h new file mode 100644 index 000000000..dd8f6abb2 --- /dev/null +++ b/public/sdk/inc/mfc42/afxdb.h @@ -0,0 +1,1042 @@ +// This is a part of the Microsoft Foundation Classes C++ library. +// Copyright (C) 1992-1995 Microsoft Corporation +// All rights reserved. +// +// This source code is only intended as a supplement to the +// Microsoft Foundation Classes Reference and related +// electronic documentation provided with the library. +// See these sources for detailed information regarding the +// Microsoft Foundation Classes product. + +#ifndef __AFXDB_H__ +#define __AFXDB_H__ + +#ifdef _AFX_NO_DB_SUPPORT + #error Database classes not supported in this library variant. +#endif + +#ifndef __AFXEXT_H__ + #include <afxext.h> +#endif + +#ifndef __AFXDB__H__ + #include <afxdb_.h> // shared header DAO database classes +#endif + +// include standard SQL/ODBC "C" APIs +#ifndef __SQL + #include <sql.h> // core +#endif +#ifndef __SQLEXT + #include <sqlext.h> // extensions +#endif + +#ifdef _AFX_MINREBUILD +#pragma component(minrebuild, off) +#endif +#ifndef _AFX_FULLTYPEINFO +#pragma component(mintypeinfo, on) +#endif + +#ifndef _AFX_NOFORCE_LIBS +#ifndef _MAC + +///////////////////////////////////////////////////////////////////////////// +// Win32 libraries + +#ifdef _AFXDLL + #if defined(_DEBUG) && !defined(_AFX_MONOLITHIC) + #ifndef _UNICODE + #pragma comment(lib, "mfcd42d.lib") + #else + #pragma comment(lib, "mfcd42ud.lib") + #endif + #endif +#endif + +#pragma comment(lib, "odbc32.lib") +#pragma comment(lib, "odbccp32.lib") + +#else //!_MAC + +///////////////////////////////////////////////////////////////////////////// +// Macintosh libraries + +#ifdef _AFXDLL + #ifdef _DEBUG + #pragma comment(lib, "mfcd42pd.lib") + #else + #pragma comment(lib, "mfcd42p.lib") + #endif +#endif + +#ifdef _MPPC_ +#pragma comment(lib, "odbccfgp.lib") +#pragma comment(lib, "odbcdrvp.lib") +#else +#pragma comment(lib, "odbccfgm.lib") +#pragma comment(lib, "odbcdrvm.lib") +#ifdef _DEBUG +#pragma comment (lib, "aslmd.lib") +#else +#pragma comment (lib, "aslm.lib") +#endif +#endif + +#endif //_MAC +#endif //!_AFX_NOFORCE_LIBS + +///////////////////////////////////////////////////////////////////////////// + +#ifdef _AFX_PACKING +#pragma pack(push, _AFX_PACKING) +#endif + +///////////////////////////////////////////////////////////////////////////// +// AFXDB - MFC SQL/ODBC/Database support + +// Classes declared in this file + + //CException + class CDBException; // abnormal return value + + //CFieldExchange + class CFieldExchange; // Recordset Field Exchange + + //CObject + class CDatabase; // Connecting to databases + class CRecordset; // Data result sets + +//CObject + //CCmdTarget; + //CWnd + //CView + //CScrollView + //CFormView + class CRecordView; // view records with a form + +// Non CObject classes +class CDBVariant; +struct CRecordsetStatus; +struct CFieldInfo; +struct CODBCFieldInfo; +struct CODBCParamInfo; + +///////////////////////////////////////////////////////////////////////////// + +// ODBC helpers +// return code left in 'nRetCode' + +// This MACRO is now out-of-date (kept for backward compatibility) +#define AFX_ODBC_CALL(SQLFunc) \ + do \ + { \ + } while ((nRetCode = (SQLFunc)) == SQL_STILL_EXECUTING) + +// Not really required, but kept for compatibilty +#define AFX_SQL_SYNC(SQLFunc) \ + do \ + { \ + nRetCode = SQLFunc; \ + } while (0) + +// Now out-of-date (prs not used) but kept for compatibility +#define AFX_SQL_ASYNC(prs, SQLFunc) AFX_ODBC_CALL(SQLFunc) + +// Max display length in chars of timestamp (date & time) value +#define TIMESTAMP_PRECISION 23 + +// AFXDLL support +#undef AFX_DATA +#define AFX_DATA AFX_DB_DATA + +// Miscellaneous sizing info +#define MAX_CURRENCY 30 // Max size of Currency($) string +#define MAX_TNAME_LEN 64 // Max size of table names +#define MAX_FNAME_LEN 64 // Max size of field names +#define MAX_DBNAME_LEN 32 // Max size of a database name +#define MAX_DNAME_LEN 256 // Max size of Recordset names +#define MAX_CONNECT_LEN 512 // Max size of Connect string +#define MAX_CURSOR_NAME 18 // Max size of a cursor name +#define DEFAULT_FIELD_TYPE SQL_TYPE_NULL // pick "C" data type to match SQL data type + +// Timeout and net wait defaults +#define DEFAULT_LOGIN_TIMEOUT 15 // seconds to before fail on connect +#define DEFAULT_QUERY_TIMEOUT 15 // seconds to before fail waiting for results + +// Field Flags, used to indicate status of fields +#define AFX_SQL_FIELD_FLAG_DIRTY 0x1 +#define AFX_SQL_FIELD_FLAG_NULL 0x2 + +// Update options flags +#define AFX_SQL_SETPOSUPDATES 0x0001 +#define AFX_SQL_POSITIONEDSQL 0x0002 +#define AFX_SQL_GDBOUND 0x0004 + +///////////////////////////////////////////////////////////////////////////// +// CDBException - something gone wrong + +// Dbkit extended error codes +#define AFX_SQL_ERROR 1000 +#define AFX_SQL_ERROR_CONNECT_FAIL AFX_SQL_ERROR+1 +#define AFX_SQL_ERROR_RECORDSET_FORWARD_ONLY AFX_SQL_ERROR+2 +#define AFX_SQL_ERROR_EMPTY_COLUMN_LIST AFX_SQL_ERROR+3 +#define AFX_SQL_ERROR_FIELD_SCHEMA_MISMATCH AFX_SQL_ERROR+4 +#define AFX_SQL_ERROR_ILLEGAL_MODE AFX_SQL_ERROR+5 +#define AFX_SQL_ERROR_MULTIPLE_ROWS_AFFECTED AFX_SQL_ERROR+6 +#define AFX_SQL_ERROR_NO_CURRENT_RECORD AFX_SQL_ERROR+7 +#define AFX_SQL_ERROR_NO_ROWS_AFFECTED AFX_SQL_ERROR+8 +#define AFX_SQL_ERROR_RECORDSET_READONLY AFX_SQL_ERROR+9 +#define AFX_SQL_ERROR_SQL_NO_TOTAL AFX_SQL_ERROR+10 +#define AFX_SQL_ERROR_ODBC_LOAD_FAILED AFX_SQL_ERROR+11 +#define AFX_SQL_ERROR_DYNASET_NOT_SUPPORTED AFX_SQL_ERROR+12 +#define AFX_SQL_ERROR_SNAPSHOT_NOT_SUPPORTED AFX_SQL_ERROR+13 +#define AFX_SQL_ERROR_API_CONFORMANCE AFX_SQL_ERROR+14 +#define AFX_SQL_ERROR_SQL_CONFORMANCE AFX_SQL_ERROR+15 +#define AFX_SQL_ERROR_NO_DATA_FOUND AFX_SQL_ERROR+16 +#define AFX_SQL_ERROR_ROW_UPDATE_NOT_SUPPORTED AFX_SQL_ERROR+17 +#define AFX_SQL_ERROR_ODBC_V2_REQUIRED AFX_SQL_ERROR+18 +#define AFX_SQL_ERROR_NO_POSITIONED_UPDATES AFX_SQL_ERROR+19 +#define AFX_SQL_ERROR_LOCK_MODE_NOT_SUPPORTED AFX_SQL_ERROR+20 +#define AFX_SQL_ERROR_DATA_TRUNCATED AFX_SQL_ERROR+21 +#define AFX_SQL_ERROR_ROW_FETCH AFX_SQL_ERROR+22 +#define AFX_SQL_ERROR_INCORRECT_ODBC AFX_SQL_ERROR+23 +#define AFX_SQL_ERROR_UPDATE_DELETE_FAILED AFX_SQL_ERROR+24 +#define AFX_SQL_ERROR_DYNAMIC_CURSOR_NOT_SUPPORTED AFX_SQL_ERROR+25 +#define AFX_SQL_ERROR_FIELD_NOT_FOUND AFX_SQL_ERROR+26 +#define AFX_SQL_ERROR_BOOKMARKS_NOT_SUPPORTED AFX_SQL_ERROR+27 +#define AFX_SQL_ERROR_BOOKMARKS_NOT_ENABLED AFX_SQL_ERROR+28 +#define AFX_SQL_ERROR_MAX AFX_SQL_ERROR+29 + +class CDBException : public CException +{ + DECLARE_DYNAMIC(CDBException) + +// Attributes +public: + RETCODE m_nRetCode; + CString m_strError; + CString m_strStateNativeOrigin; + +// Implementation (use AfxThrowDBException to create) +public: + CDBException(RETCODE nRetCode = SQL_SUCCESS); + + virtual void BuildErrorString(CDatabase* pdb, HSTMT hstmt, + BOOL bTrace = TRUE); + void Empty(); + virtual ~CDBException(); + + virtual BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError, + PUINT pnHelpContext = NULL); + +#ifdef _DEBUG + void TraceErrorMessage(LPCTSTR szTrace) const; +#endif // DEBUG + +}; + +void AFXAPI AfxThrowDBException(RETCODE nRetCode, CDatabase* pdb, HSTMT hstmt); + +////////////////////////////////////////////////////////////////////////////// +// CDatabase - a SQL Database + +class CDatabase : public CObject +{ + DECLARE_DYNAMIC(CDatabase) + +// Constructors +public: + CDatabase(); + + enum DbOpenOptions + { + openExclusive = 0x0001, // Not implemented + openReadOnly = 0x0002, // Open database read only + useCursorLib = 0x0004, // Use ODBC cursor lib + noOdbcDialog = 0x0008, // Don't display ODBC Connect dialog + forceOdbcDialog = 0x0010, // Always display ODBC connect dialog + }; + + virtual BOOL Open(LPCTSTR lpszDSN, BOOL bExclusive = FALSE, + BOOL bReadonly = FALSE, LPCTSTR lpszConnect = _T("ODBC;"), + BOOL bUseCursorLib = TRUE); + virtual BOOL OpenEx(LPCTSTR lpszConnectString, DWORD dwOptions = 0); + virtual void Close(); + +// Attributes +public: + HDBC m_hdbc; + + BOOL IsOpen() const; // Database successfully opened? + BOOL CanUpdate() const; + BOOL CanTransact() const; // Are Transactions supported? + + CString GetDatabaseName() const; + const CString& GetConnect() const; + + DWORD GetBookmarkPersistence() const; + int GetCursorCommitBehavior() const; + int GetCursorRollbackBehavior() const; + +// Operations +public: + void SetLoginTimeout(DWORD dwSeconds); + void SetQueryTimeout(DWORD dwSeconds); + + // transaction control + BOOL BeginTrans(); + BOOL CommitTrans(); + BOOL Rollback(); + + void ExecuteSQL(LPCTSTR lpszSQL); + + // Cancel asynchronous operation + void Cancel(); + +// Overridables +public: + // set special options + virtual void OnSetOptions(HSTMT hstmt); + +// Implementation +public: + virtual ~CDatabase(); + +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; + + BOOL m_bTransactionPending; +#endif //_DEBUG + + // general error check + virtual BOOL Check(RETCODE nRetCode) const; + + virtual void BindParameters(HSTMT hstmt); + + void ReplaceBrackets(LPTSTR lpchSQL); + BOOL m_bStripTrailingSpaces; + BOOL m_bIncRecordCountOnAdd; + BOOL m_bAddForUpdate; + char m_chIDQuoteChar; + char m_reserved1[3]; // pad to even 4 bytes + + void SetSynchronousMode(BOOL bSynchronous); // Obsolete, doe nothing + +protected: + CString m_strConnect; + + CPtrList m_listRecordsets; // maintain list to ensure CRecordsets all closed + + int nRefCount; + BOOL m_bUpdatable; + + BOOL m_bTransactions; + SWORD m_nTransactionCapable; + SWORD m_nCursorCommitBehavior; + SWORD m_nCursorRollbackBehavior; + DWORD m_dwUpdateOptions; + DWORD m_dwBookmarkAttributes; // cache driver bookmark persistence + + DWORD m_dwLoginTimeout; + HSTMT m_hstmt; + + DWORD m_dwQueryTimeout; + + virtual void ThrowDBException(RETCODE nRetCode); + void AllocConnect(DWORD dwOptions); + BOOL Connect(DWORD dwOptions); + void VerifyConnect(); + void GetConnectInfo(); + void Free(); + + // friend classes that call protected CDatabase overridables + friend class CRecordset; + friend class CFieldExchange; + friend class CDBException; +}; + +////////////////////////////////////////////////////////////////////////////// +// CFieldExchange - for field exchange +class CFieldExchange +{ +// Attributes +public: + enum RFX_Operation + { + BindParam, // register users parameters with ODBC SQLBindParameter + RebindParam, // migrate param values to proxy array before Requery + BindFieldToColumn, // register users fields with ODBC SQLBindCol + BindFieldForUpdate, // temporarily bind columns before update (via SQLSetPos) + UnbindFieldForUpdate, // unbind columns after update (via SQLSetPos) + Fixup, // Set string lengths, clear status bits + MarkForAddNew, // Prepare fields and flags for addnew operation + MarkForUpdate, // Prepare fields and flags for update operation + Name, // append dirty field name + NameValue, // append dirty name=value + Value, // append dirty value or parameter marker + SetFieldNull, // Set status bit for null value + StoreField, // archive values of current record + LoadField, // reload archived values into current record + AllocCache, // allocate cache used for dirty field check + AllocMultiRowBuffer, // allocate buffer holding multi rows of data + DeleteMultiRowBuffer, // delete buffer holding multi rows of data +#ifdef _DEBUG + DumpField, // dump bound field name and value +#endif + }; + UINT m_nOperation; // Type of exchange operation + CRecordset* m_prs; // recordset handle + +// Operations + enum FieldType + { + noFieldType = -1, + outputColumn = 0, + param = SQL_PARAM_INPUT, + inputParam = param, + outputParam = SQL_PARAM_OUTPUT, + inoutParam = SQL_PARAM_INPUT_OUTPUT, + }; + +// Operations (for implementors of RFX procs) + BOOL IsFieldType(UINT* pnField); + + // Indicate purpose of subsequent RFX calls + void SetFieldType(UINT nFieldType); + +// Implementation + CFieldExchange(UINT nOperation, CRecordset* prs, void* pvField = NULL); + + void Default(LPCTSTR szName, + void* pv, LONG* plLength, int nCType, UINT cbValue, UINT cbPrecision); + + // long binary helpers + long GetLongBinarySize(int nField); + void GetLongBinaryData(int nField, CLongBinary& lb, long* plSize); + BYTE* ReallocLongBinary(CLongBinary& lb, long lSizeRequired, + long lReallocSize); + + // Current type of field + UINT m_nFieldType; + + UINT m_nFieldFound; + + CString* m_pstr; // Field name or destination for building various SQL clauses + BOOL m_bField; // Value to set for SetField operation + void* m_pvField; // For indicating an operation on a specific field + LPCTSTR m_lpszSeparator; // append after field names + UINT m_nFields; // count of fields for various operations + UINT m_nParams; // count of fields for various operations + UINT m_nParamFields; // count of fields for various operations + HSTMT m_hstmt; // For SQLBindParameter on update statement + long m_lDefaultLBFetchSize; // For fetching CLongBinary data of unknown len + long m_lDefaultLBReallocSize; // For fetching CLongBinary data of unknown len + +#ifdef _DEBUG + CDumpContext* m_pdcDump; +#endif //_DEBUG + +}; + +///////////////////////////////////////////////////////////////////////////// +// Recordset Field Exchange helpers +void AFXAPI AfxStoreField(CRecordset& rs, UINT nField, void* pvField); +void AFXAPI AfxLoadField(CRecordset& rs, UINT nField, + void* pvField, long* plLength); +BOOL AFXAPI AfxCompareValueByRef(void* pvData, void* pvCache, int nDataType); +void AFXAPI AfxCopyValueByRef(void* pvCache, void* pvData, + long* plLength, int nDataType); + +///////////////////////////////////////////////////////////////////////////// +// Standard Recordset Field Exchange routines + +// text data +void AFXAPI RFX_Text(CFieldExchange* pFX, LPCTSTR szName, CString& value, + // Default max length for char and varchar, default datasource type + int nMaxLength = 255, int nColumnType = SQL_VARCHAR, short nScale = 0); + +// boolean data +void AFXAPI RFX_Bool(CFieldExchange* pFX, LPCTSTR szName, BOOL& value); + +// integer data +void AFXAPI RFX_Long(CFieldExchange* pFX, LPCTSTR szName, long& value); +void AFXAPI RFX_Int(CFieldExchange* pFX, LPCTSTR szName, int& value); +void AFXAPI RFX_Single(CFieldExchange* pFX, LPCTSTR szName, float& value); +void AFXAPI RFX_Double(CFieldExchange* pFX, LPCTSTR szName, double& value); + +// date and time +void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, CTime& value); +void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, TIMESTAMP_STRUCT& value); + +// Binary data +void AFXAPI RFX_Binary(CFieldExchange* pFX, LPCTSTR szName, CByteArray& value, + // Default max length is for binary and varbinary + int nMaxLength = 255); +void AFXAPI RFX_Byte(CFieldExchange* pFX, LPCTSTR szName, BYTE& value); +void AFXAPI RFX_LongBinary(CFieldExchange* pFX, LPCTSTR szName, CLongBinary& value); + +///////////////////////////////////////////////////////////////////////////// +// Bulk Recordset Field Exchange helpers +void AFXAPI AfxRFXBulkDefault(CFieldExchange* pFX, LPCTSTR szName, + void* pv, long* rgLengths, int nCType, UINT cbValue); + +///////////////////////////////////////////////////////////////////////////// +// Bulk Recordset Field Exchange routines + +void AFXAPI RFX_Text_Bulk(CFieldExchange* pFX, LPCTSTR szName, + LPSTR* prgStrVals, long** prgLengths, int nMaxLength); + +void AFXAPI RFX_Bool_Bulk(CFieldExchange* pFX, LPCTSTR szName, + BOOL** prgBoolVals, long** prgLengths); +void AFXAPI RFX_Int_Bulk(CFieldExchange* pFX, LPCTSTR szName, + int** prgIntVals, long** prgLengths); +void AFXAPI RFX_Long_Bulk(CFieldExchange* pFX, LPCTSTR szName, + long** prgLongVals, long** prgLengths); + +void AFXAPI RFX_Single_Bulk(CFieldExchange* pFX, LPCTSTR szName, + float** prgFltVals, long** prgLengths); +void AFXAPI RFX_Double_Bulk(CFieldExchange* pFX, LPCTSTR szName, + double** prgDblVals, long** prgLengths); + +void AFXAPI RFX_Date_Bulk(CFieldExchange* pFX, LPCTSTR szName, + TIMESTAMP_STRUCT** prgTSVals, long** prgLengths); + +void AFXAPI RFX_Byte_Bulk(CFieldExchange* pFX, LPCTSTR szName, + BYTE** prgByteVals, long** prgLengths); +void AFXAPI RFX_Binary_Bulk(CFieldExchange* pFX, LPCTSTR szName, + BYTE** prgByteVals, long** prgLengths, int nMaxLength); + +///////////////////////////////////////////////////////////////////////////// +// Database Dialog Data Exchange cover routines +// Cover routines provide database semantics on top of DDX routines + +// simple text operations +void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, BYTE& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, int& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, UINT& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, long& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, DWORD& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, double& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, float& value, CRecordset* pRecordset); + +// special control types +void AFXAPI DDX_FieldCheck(CDataExchange* pDX, int nIDC, int& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldRadio(CDataExchange* pDX, int nIDC, int& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldLBString(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldCBString(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldLBIndex(CDataExchange* pDX, int nIDC, int& index, CRecordset* pRecordset); +void AFXAPI DDX_FieldCBIndex(CDataExchange* pDX, int nIDC, int& index, CRecordset* pRecordset); +void AFXAPI DDX_FieldLBStringExact(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldCBStringExact(CDataExchange* pDX, int nIDC, CString& value, CRecordset* pRecordset); +void AFXAPI DDX_FieldScroll(CDataExchange* pDX, int nIDC, int& value, CRecordset* pRecordset); + +////////////////////////////////////////////////////////////////////////////// +// CRecordset - the result of a SQL Statement + +#define AFX_DB_USE_DEFAULT_TYPE (0xFFFFFFFF) + +// Most Move constants out of date +// #define AFX_MOVE_FIRST 0x80000000L +// #define AFX_MOVE_PREVIOUS (-1L) +#define AFX_MOVE_REFRESH 0L +// #define AFX_MOVE_NEXT (+1L) +// #define AFX_MOVE_LAST 0x7fffffffL + +#define AFX_RECORDSET_STATUS_OPEN (+1L) +#define AFX_RECORDSET_STATUS_CLOSED 0L +#define AFX_RECORDSET_STATUS_UNKNOWN (-1L) + +class CRecordset : public CObject +{ + DECLARE_DYNAMIC(CRecordset) + +// Constructor +public: + CRecordset(CDatabase* pDatabase = NULL); + +public: + virtual ~CRecordset(); + + enum OpenType + { + dynaset, // uses SQLExtendedFetch, keyset driven cursor + snapshot, // uses SQLExtendedFetch, static cursor + forwardOnly, // uses SQLFetch + dynamic // uses SQLExtendedFetch, dynamic cursor + }; + + enum OpenOptions + { + none = 0x0, + readOnly = 0x0004, + appendOnly = 0x0008, + skipDeletedRecords = 0x0010, // turn on skipping of deleted records, Will slow Move(n). + noDirtyFieldCheck = 0x0020, // disable automatic dirty field checking + useBookmarks = 0x0100, // turn on bookmark support + useMultiRowFetch = 0x0200, // turn on multi-row fetch model + userAllocMultiRowBuffers = 0x0400, // if multi-row fetch on, user will alloc memory for buffers + useExtendedFetch = 0x0800, // use SQLExtendedFetch with forwardOnly type recordsets + executeDirect = 0x2000, // Directly execute SQL rather than prepared execute + optimizeBulkAdd = 0x4000, // Use prepared HSTMT for multiple AddNews, dirty fields must not change. + firstBulkAdd = 0x8000, // INTERNAL to MFC, don't specify on Open. + }; + virtual BOOL Open(UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, + LPCTSTR lpszSQL = NULL, DWORD dwOptions = none); + virtual void Close(); + +// Attributes +public: + HSTMT m_hstmt; // Source statement for this resultset + CDatabase* m_pDatabase; // Source database for this resultset + + CString m_strFilter; // Where clause + CString m_strSort; // Order By Clause + + BOOL CanAppend() const; // Can AddNew be called? + BOOL CanRestart() const; // Can Requery be called to restart a query? + BOOL CanScroll() const; // Can MovePrev and MoveFirst be called? + BOOL CanTransact() const; // Are Transactions supported? + BOOL CanUpdate() const; // Can Edit/AddNew/Delete be called? + BOOL CanBookmark() const; // Can Get/SetBookmark be called? + + const CString& GetSQL() const; // SQL executed for this recordset + const CString& GetTableName() const; // Table name + + BOOL IsOpen() const; // Recordset successfully opened? + BOOL IsBOF() const; // Beginning Of File + BOOL IsEOF() const; // End Of File + BOOL IsDeleted() const; // On a deleted record + + BOOL IsFieldDirty(void *pv); // has field been updated? + BOOL IsFieldNull(void *pv); // is field NULL valued? + BOOL IsFieldNullable(void *pv); // can field be set to a NULL value + + long GetRecordCount() const; // Records seen so far or -1 if unknown + void GetStatus(CRecordsetStatus& rStatus) const; + +// Operations +public: + // cursor operations + void MoveNext(); + void MovePrev(); + void MoveFirst(); + void MoveLast(); + virtual void Move(long nRows, WORD wFetchType = SQL_FETCH_RELATIVE); + + void SetAbsolutePosition(long nRows); + + void GetBookmark(CDBVariant& varBookmark); + void SetBookmark(const CDBVariant& varBookmark); + + virtual void SetRowsetSize(DWORD dwNewRowsetSize); + DWORD GetRowsetSize() const; + DWORD GetRowsFetched() const; + virtual void CheckRowsetError(RETCODE nRetCode); + void RefreshRowset(WORD wRow, WORD wLockType = SQL_LOCK_NO_CHANGE); + void SetRowsetCursorPosition(WORD wRow, WORD wLockType = SQL_LOCK_NO_CHANGE); + WORD GetRowStatus(WORD wRow) const; + + // edit buffer operations + virtual void AddNew(); // add new record at the end + virtual void Edit(); // start editing + virtual BOOL Update(); // update it + virtual void Delete(); // delete the current record + void CancelUpdate(); // cancel pending Edit/AddNew + + BOOL FlushResultSet() const; + + // field operations + short GetODBCFieldCount() const; + void GetODBCFieldInfo(short nIndex, CODBCFieldInfo& fieldinfo); + void GetODBCFieldInfo(LPCTSTR lpszName, CODBCFieldInfo& fieldinfo); + void GetFieldValue(LPCTSTR lpszName, CDBVariant& varValue, + short nFieldType = DEFAULT_FIELD_TYPE); + void GetFieldValue(short nIndex, CDBVariant& varValue, + short nFieldType = DEFAULT_FIELD_TYPE); + void GetFieldValue(LPCTSTR lpszName, CString& strValue); + void GetFieldValue(short nIndex, CString& strValue); + + void SetFieldDirty(void *pv, BOOL bDirty = TRUE); + void SetFieldNull(void *pv, BOOL bNull = TRUE); + + // locking control during Edit + enum LockMode + { + optimistic, + pessimistic, + }; + void SetLockingMode(UINT nMode); + + // Recordset operations + virtual BOOL Requery(); // Re-execute query based on new params + + // Cancel asynchronous operation + void Cancel(); + +// Overridables +public: + // Get default connect string + virtual CString GetDefaultConnect(); + + // Get SQL to execute + virtual CString GetDefaultSQL(); + + // set special options + virtual void OnSetOptions(HSTMT hstmt); + + // for recordset field exchange + virtual void DoFieldExchange(CFieldExchange* pFX); + virtual void DoBulkFieldExchange(CFieldExchange* pFX); + +// Implementation +public: +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif //_DEBUG + + virtual BOOL Check(RETCODE nRetCode) const; // general error check + + void InitRecord(); + void ResetCursor(); + void CheckRowsetCurrencyStatus(UWORD wFetchType, long nRows); + RETCODE FetchData(UWORD wFetchType, SDWORD nRow, + DWORD* pdwRowsFetched); + void SkipDeletedRecords(UWORD wFetchType, long nRows, + DWORD* pdwRowsFetched, RETCODE* pnRetCode); + virtual void SetRowsetCurrencyStatus(RETCODE nRetCode, + UWORD wFetchType, long nRows, DWORD dwRowsFetched); + + virtual void PreBindFields(); // called before data fields are bound + UINT m_nFields; // number of RFX fields + UINT m_nParams; // number of RFX params + BOOL m_bCheckCacheForDirtyFields; // switch for dirty field checking + BOOL m_bRebindParams; // date or UNICODE text parameter existence flag + BOOL m_bLongBinaryColumns; // long binary column existence flag + BOOL m_bUseUpdateSQL; // uses SQL-based updates + DWORD m_dwOptions; // archive dwOptions on Open + SWORD m_nResultCols; // number of columns in result set + BOOL m_bUseODBCCursorLib; // uses ODBC cursor lib if m_pDatabase not Open + CODBCFieldInfo* m_rgODBCFieldInfos; // Array of field info structs with ODBC meta-data + CFieldInfo* m_rgFieldInfos; // Array of field info structs with MFC specific field data + CMapPtrToPtr m_mapFieldIndex; // Map of member address to field index + CMapPtrToPtr m_mapParamIndex; // Map of member address to field index + + BOOL IsSQLUpdatable(LPCTSTR lpszSQL); + BOOL IsSelectQueryUpdatable(LPCTSTR lpszSQL); + static BOOL PASCAL IsJoin(LPCTSTR lpszJoinClause); + static LPCTSTR PASCAL FindSQLToken(LPCTSTR lpszSQL, LPCTSTR lpszSQLToken); + + // RFX Operations on fields of CRecordset + UINT BindParams(HSTMT hstmt); + void RebindParams(HSTMT hstmt); + UINT BindFieldsToColumns(); + void BindFieldsForUpdate(); + void UnbindFieldsForUpdate(); + void Fixups(); + UINT AppendNames(CString* pstr, LPCTSTR szSeparator); + UINT AppendValues(HSTMT hstmt, CString* pstr, LPCTSTR szSeparator); + UINT AppendNamesValues(HSTMT hstmt, CString* pstr, LPCTSTR szSeparator); + void StoreFields(); + void LoadFields(); + void MarkForAddNew(); + void MarkForUpdate(); + void AllocDataCache(); + void FreeDataCache(); +#ifdef _DEBUG + void DumpFields(CDumpContext& dc) const; +#endif //_DEBUG + + // RFX operation helper functions + virtual void ThrowDBException(RETCODE nRetCode, HSTMT hstmt = SQL_NULL_HSTMT); + + int GetBoundFieldIndex(void* pv); + int GetBoundParamIndex(void* pv); + short GetFieldIndexByName(LPCTSTR lpszFieldName); + + void AllocStatusArrays(); + long* GetFieldLengthBuffer(DWORD nField, int nFieldType); // for fields & params + + BYTE GetFieldStatus(DWORD nField); + void SetFieldStatus(DWORD nField, BYTE bFlags); + void ClearFieldStatus(); + + BOOL IsFieldStatusDirty(DWORD nField) const; + void SetDirtyFieldStatus(DWORD nField); + void ClearDirtyFieldStatus(DWORD nField); + + BOOL IsFieldStatusNull(DWORD nField) const; + void SetNullFieldStatus(DWORD nField); + void ClearNullFieldStatus(DWORD nField); + + BOOL IsParamStatusNull(DWORD nField) const; + void SetNullParamStatus(DWORD nField); + void ClearNullParamStatus(DWORD nField); + + BOOL IsFieldNullable(DWORD nField) const; + + void** m_pvFieldProxy; + void** m_pvParamProxy; + UINT m_nProxyFields; + UINT m_nProxyParams; + + // GetFieldValue helpers + static short PASCAL GetDefaultFieldType(short nSQLType); + static void* PASCAL GetDataBuffer(CDBVariant& varValue, short nFieldType, + int* pnLen, short nSQLType, UDWORD nPrecision); + static int PASCAL GetTextLen(short nSQLType, UDWORD nPrecision); + static long PASCAL GetData(CDatabase* pdb, HSTMT hstmt, short nFieldIndex, + short nFieldType, LPVOID pvData, int nLen, short nSQLType); + static void PASCAL GetLongBinaryDataAndCleanup(CDatabase* pdb, HSTMT hstmt, + short nFieldIndex, long nActualSize, LPVOID* ppvData, int nLen, + CDBVariant& varValue, short nSQLType); + static void PASCAL GetLongCharDataAndCleanup(CDatabase* pdb, HSTMT hstmt, + short nFieldIndex, long nActualSize, LPVOID* ppvData, int nLen, + CString& strValue, short nSQLType); + +protected: + UINT m_nOpenType; + UINT m_nDefaultType; + enum EditMode + { + noMode, + edit, + addnew + }; + long m_lOpen; + UINT m_nEditMode; + BOOL m_bEOFSeen; + long m_lRecordCount; + long m_lCurrentRecord; + CString m_strCursorName; + // Perform operation based on m_nEditMode + BOOL UpdateInsertDelete(); + BOOL m_nLockMode; // Control concurrency for Edit() + UDWORD m_dwDriverConcurrency; // driver supported concurrency types + UDWORD m_dwConcurrency; // requested concurrency type + UWORD* m_rgRowStatus; // row status used by SQLExtendedFetch and SQLSetPos + DWORD m_dwRowsFetched; // number of rows fetched by SQLExtendedFetch + HSTMT m_hstmtUpdate; + BOOL m_bRecordsetDb; + BOOL m_bBOF; + BOOL m_bEOF; + BOOL m_bUpdatable; // Is recordset updatable? + BOOL m_bAppendable; + CString m_strSQL; // SQL statement for recordset + CString m_strUpdateSQL; // SQL statement for updates + CString m_strTableName; // source table of recordset + BOOL m_bScrollable; // supports MovePrev + BOOL m_bDeleted; + int m_nFieldsBound; + BYTE* m_pbFieldFlags; + BYTE* m_pbParamFlags; + LONG* m_plParamLength; + DWORD m_dwInitialGetDataLen; // Initial GetFieldValue alloc size for long data + DWORD m_dwRowsetSize; + DWORD m_dwAllocatedRowsetSize; + +protected: + CString m_strRequerySQL; // archive SQL string for use in Requery() + CString m_strRequeryFilter; // archive filter string for use in Requery() + CString m_strRequerySort; // archive sort string for use in Requery() + + void SetState(int nOpenType, LPCTSTR lpszSQL, DWORD dwOptions); + BOOL AllocHstmt(); + void BuildSQL(LPCTSTR lpszSQL); + void PrepareAndExecute(); + + void BuildSelectSQL(); + void AppendFilterAndSortSQL(); + BOOL IsRecordsetUpdatable(); + + void VerifyDriverBehavior(); + DWORD VerifyCursorSupport(); + void EnableBookmarks(); + void SetUpdateMethod(); + void SetConcurrencyAndCursorType(HSTMT hstmt, DWORD dwScrollOptions); + void AllocAndCacheFieldInfo(); + void AllocRowset(); + void FreeRowset(); + + void ExecuteSetPosUpdate(); + void PrepareUpdateHstmt(); + void BuildUpdateSQL(); + void ExecuteUpdateSQL(); + void SendLongBinaryData(HSTMT hstmt); + virtual long GetLBFetchSize(long lOldSize); // CLongBinary fetch chunking + virtual long GetLBReallocSize(long lOldSize); // CLongBinary realloc chunking + + friend class CFieldExchange; + friend class CRecordView; +}; + +///////////////////////////////////////////////////////////////////////////// +// Info helper definitions +#define AFX_CURRENT_RECORD_UNDEFINED (-2) +#define AFX_CURRENT_RECORD_BOF (-1) + +// For returning status for a recordset +struct CRecordsetStatus +{ + long m_lCurrentRecord; // -2=Unknown,-1=BOF,0=1st record. . . + BOOL m_bRecordCountFinal;// Have we counted all records? +}; + +// Must maintian data binding info +struct CFieldInfo +{ + // MFC specific info + void* m_pvDataCache; + long m_nLength; + int m_nDataType; + BYTE m_bStatus; +#ifdef _DEBUG + void* m_pvBindAddress; +#endif +}; + +struct CODBCFieldInfo +{ + // meta data from ODBC + CString m_strName; + SWORD m_nSQLType; + UDWORD m_nPrecision; + SWORD m_nScale; + SWORD m_nNullability; +}; + +struct CODBCParamInfo +{ + // meta data from ODBC + SWORD m_nSQLType; + UDWORD m_nPrecision; + SWORD m_nScale; + SWORD m_nNullability; +}; + + +///////////////////////////////////////////////////////////////////////////// +// CDBVariant + +#define DBVT_NULL 0 +#define DBVT_BOOL 1 +#define DBVT_UCHAR 2 +#define DBVT_SHORT 3 +#define DBVT_LONG 4 +#define DBVT_SINGLE 5 +#define DBVT_DOUBLE 6 +#define DBVT_DATE 7 +#define DBVT_STRING 8 +#define DBVT_BINARY 9 + +class CDBVariant +{ +// Constructor +public: + CDBVariant(); + +// Attributes +public: + DWORD m_dwType; + + union + { + BOOL m_boolVal; + unsigned char m_chVal; + short m_iVal; + long m_lVal; + float m_fltVal; + double m_dblVal; + TIMESTAMP_STRUCT* m_pdate; + CString* m_pstring; + CLongBinary* m_pbinary; + }; + +// Operations + void Clear(); + +// Implementation +public: + virtual ~CDBVariant(); +}; + +///////////////////////////////////////////////////////////////////////////// +// CRecordView - form for viewing data records + +class CRecordView : public CFormView +{ + DECLARE_DYNAMIC(CRecordView) + +// Construction +protected: // must derive your own class + CRecordView(LPCTSTR lpszTemplateName); + CRecordView(UINT nIDTemplate); + +// Attributes +public: + virtual CRecordset* OnGetRecordset() = 0; + + BOOL IsOnLastRecord(); + BOOL IsOnFirstRecord(); + +// Operations +public: + virtual BOOL OnMove(UINT nIDMoveCommand); + +// Implementation +public: + virtual ~CRecordView(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + virtual void OnInitialUpdate(); + +protected: + BOOL m_bOnFirstRecord; + BOOL m_bOnLastRecord; + + //{{AFX_MSG(CRecordView) + afx_msg void OnUpdateRecordFirst(CCmdUI* pCmdUI); + afx_msg void OnUpdateRecordPrev(CCmdUI* pCmdUI); + afx_msg void OnUpdateRecordNext(CCmdUI* pCmdUI); + afx_msg void OnUpdateRecordLast(CCmdUI* pCmdUI); + //}}AFX_MSG + afx_msg void OnMove(int cx, int cy); + + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// +// Inline function declarations + +#ifdef _AFX_PACKING +#pragma pack(pop) +#endif + +#ifdef _AFX_ENABLE_INLINES +#define _AFXDBCORE_INLINE inline +#define _AFXDBRFX_INLINE inline +#define _AFXDBVIEW_INLINE inline +#include <afxdb.inl> +#undef _AFXDBVIEW_INLINE +#undef _AFXDBCORE_INLINE +#undef _AFXDBRFX_INLINE +#endif + +#undef AFX_DATA +#define AFX_DATA + +#ifdef _AFX_MINREBUILD +#pragma component(minrebuild, on) +#endif +#ifndef _AFX_FULLTYPEINFO +#pragma component(mintypeinfo, off) +#endif + +#endif //__AFXDB_H__ + +///////////////////////////////////////////////////////////////////////////// |