// 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 __AFXDAO_H
#define __AFXDAO_H

#ifdef _AFX_NO_DAO_SUPPORT
	#error DAO Database classes not supported in this library variant.
#endif

#ifndef __AFXDISP_H__
	#include <afxdisp.h>    // Must include this before dao headers
#endif
#ifndef _DBDAOINT_H_
	#include <dbdaoint.h>
#endif
#ifndef _DAOGETRW_H_
	#include <daogetrw.h>
#endif
#ifndef _DBDAOID_H_
	#include <dbdaoid.h>
#endif
#ifndef _DBDAOERR_H_
	#include <dbdaoerr.h>
#endif

#ifndef __AFXDB__H__
	#include <afxdb_.h> // shared header with ODBC database classes
#endif

#ifndef __AFXEXT_H__
	#include <afxext.h> // for CFormView
#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, "mfco42d.lib")
			#pragma comment(lib, "mfcd42d.lib")
		#else
			#pragma comment(lib, "mfco42ud.lib")
			#pragma comment(lib, "mfcd42ud.lib")
		#endif
	#endif

#endif

#pragma comment(lib, "daouuid.lib")

#else //!_MAC

/////////////////////////////////////////////////////////////////////////////
// Macintosh libraries

#endif //_MAC
#endif //!_AFX_NOFORCE_LIBS

#ifdef _AFX_PACKING
#pragma pack(push, _AFX_PACKING)
#endif

////////////////////////////////////////////////////////////////////////
// AFXDAO - MFC Database support using DAO

// Classes declared in this file

	// CException
		class CDaoException;    // DAO error/exception handling

	// CObject
		class CDaoRecordView;
		class CDaoWorkspace;    // DAO engine/transaction/security manager
		class CDaoDatabase;     // DAO database manager
		class CDaoRecordset;    // DAO result set manager
		class CDaoTableDef;     // DAO base table manager
		class CDaoQueryDef;     // DAO query manager

	// Non-CObject classes
		class CDaoFieldExchange;
		struct CDaoFieldCache;
		struct CDaoErrorInfo;
		struct CDaoWorkspaceInfo;
		struct CDaoDatabaseInfo;
		struct CDaoTableDefInfo;
		struct CDaoFieldInfo;
		struct CDaoIndexInfo;
		struct CDaoRelationInfo;
		struct CDaoQueryDefInfo;
		struct CDaoParameterInfo;

/////////////////////////////////////////////////////////////////////////////
// AFXDLL support

#undef AFX_DATA
#define AFX_DATA AFX_DB_DATA

////////////////////////////////////////////////////////////////////////
// Data caching structures
struct CDaoFieldCache
{
	void* m_pvData;     // Pointer to cached data of any supported type.
	BYTE m_nStatus;     // (NULL) status cache.
	BYTE m_nDataType;       // Type of data cached.
};

////////////////////////////////////////////////////////////////////////
// Info structures

struct CDaoErrorInfo
{
// Attributes
	long m_lErrorCode;
	CString m_strSource;
	CString m_strDescription;
	CString m_strHelpFile;
	long m_lHelpContext;

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoWorkspaceInfo
{
// Attributes
	CString m_strName;              // Primary
	CString m_strUserName;          // Secondary
	BOOL m_bIsolateODBCTrans;       // All

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoDatabaseInfo
{
// Attributes
	CString m_strName;              // Primary
	BOOL m_bUpdatable;              // Primary
	BOOL m_bTransactions;           // Primary
	CString m_strVersion;           // Secondary
	long m_lCollatingOrder;         // Secondary
	short m_nQueryTimeout;          // Secondary
	CString m_strConnect;           // All

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoTableDefInfo
{
// Attributes
	CString m_strName;              // Primary
	BOOL m_bUpdatable;              // Primary
	long m_lAttributes;             // Primary
	COleDateTime m_dateCreated;     // Secondary
	COleDateTime m_dateLastUpdated; // Secondary
	CString m_strSrcTableName;      // Secondary
	CString m_strConnect;           // Secondary
	CString m_strValidationRule;    // All
	CString m_strValidationText;    // All
	long m_lRecordCount;            // All

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoFieldInfo
{
// Attributes
	CString m_strName;              // Primary
	short m_nType;                  // Primary
	long m_lSize;                   // Primary
	long m_lAttributes;             // Primary
	short m_nOrdinalPosition;       // Secondary
	BOOL m_bRequired;               // Secondary
	BOOL m_bAllowZeroLength;        // Secondary
	long m_lCollatingOrder;         // Secondary
	CString m_strForeignName;       // Secondary
	CString m_strSourceField;       // Secondary
	CString m_strSourceTable;       // Secondary
	CString m_strValidationRule;    // All
	CString m_strValidationText;    // All
	CString m_strDefaultValue;      // All

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoIndexFieldInfo
{
// Attributes
	CString m_strName;              // Primary
	BOOL m_bDescending;             // Primary

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoIndexInfo
{
// Constructors
	CDaoIndexInfo();

// Attributes
	CString m_strName;                      // Primary
	CDaoIndexFieldInfo* m_pFieldInfos;      // Primary
	short m_nFields;                        // Primary
	BOOL m_bPrimary;                        // Secondary
	BOOL m_bUnique;                         // Secondary
	BOOL m_bClustered;                      // Secondary
	BOOL m_bIgnoreNulls;                    // Secondary
	BOOL m_bRequired;                       // Secondary
	BOOL m_bForeign;                        // Secondary
	long m_lDistinctCount;                  // All

// Implementation
	virtual ~CDaoIndexInfo();
	BOOL m_bCleanupFieldInfo;

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoRelationFieldInfo
{
// Attributes
	CString m_strName;              // Primary
	CString m_strForeignName;       // Primary

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoRelationInfo
{
// Constructor
	CDaoRelationInfo();

// Attributes
	CString m_strName;              // Primary
	CString m_strTable;             // Primary
	CString m_strForeignTable;      // Primary
	long m_lAttributes;             // Secondary
	CDaoRelationFieldInfo* m_pFieldInfos;   // Secondary
	short m_nFields;                // Secondary

// Implementation
	virtual ~CDaoRelationInfo();
	BOOL m_bCleanupFieldInfo;

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoQueryDefInfo
{
// Attributes
	CString m_strName;              // Primary
	short m_nType;                  // Primary
	COleDateTime m_dateCreated;     // Secondary
	COleDateTime m_dateLastUpdated; // Secondary
	BOOL m_bUpdatable;              // Secondary
	BOOL m_bReturnsRecords;         // Secondary
	CString m_strSQL;               // All
	CString m_strConnect;           // All
	short m_nODBCTimeout;           // See readme

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

struct CDaoParameterInfo
{
// Attributes
	CString m_strName;              // Primary
	short m_nType;                  // Primary
	COleVariant m_varValue;         // Secondary

#ifdef _DEBUG
	virtual void Dump(CDumpContext& dc) const;
#endif
};

////////////////////////////////////////////////////////////////////////
// DAO Helpers
//

// Flags for getting and/or setting object properties
#define AFX_DAO_PRIMARY_INFO    0x00000001  // Get only primary
#define AFX_DAO_SECONDARY_INFO  0x00000002  // Get primary & secondary
#define AFX_DAO_ALL_INFO        0x00000004  // Get All info

// Jet engine TRUE/FALSE definitions
#define AFX_DAO_TRUE                    (-1L)
#define AFX_DAO_FALSE                   0

// Set CDaoRecordset::Open option to use m_nDefaultType
#define AFX_DAO_USE_DEFAULT_TYPE        (-1L)

// Flags used for Move/Find
#define AFX_DAO_NEXT                    (+1L)
#define AFX_DAO_PREV                    (-1L)
#define AFX_DAO_FIRST                   LONG_MIN
#define AFX_DAO_LAST                    LONG_MAX

// Default sizes for DFX function PreAlloc sizes
#define AFX_DAO_TEXT_DEFAULT_SIZE       255
#define AFX_DAO_BINARY_DEFAULT_SIZE     2048
#define AFX_DAO_LONGBINARY_DEFAULT_SIZE 32768

// Flag used for DFX functions dwBindOptions bitmask
#define AFX_DAO_ENABLE_FIELD_CACHE      0x01
#define AFX_DAO_DISABLE_FIELD_CACHE     0
#define AFX_DAO_CACHE_BY_VALUE          0x80    // MFC Internal

// Field Flags, used to indicate status of fields
#define AFX_DAO_FIELD_FLAG_DIRTY            0x01
#define AFX_DAO_FIELD_FLAG_NULL             0x02
#define AFX_DAO_FIELD_FLAG_NULLABLE_KNOWN   0x04
#define AFX_DAO_FIELD_FLAG_NULLABLE         0x08

// Extended error codes
#define NO_AFX_DAO_ERROR                        0
#define AFX_DAO_ERROR_MIN                       2000
#define AFX_DAO_ERROR_ENGINE_INITIALIZATION     AFX_DAO_ERROR_MIN + 0
#define AFX_DAO_ERROR_DFX_BIND                  AFX_DAO_ERROR_MIN + 1
#define AFX_DAO_ERROR_OBJECT_NOT_OPEN           AFX_DAO_ERROR_MIN + 2
#define AFX_DAO_ERROR_MAX                       AFX_DAO_ERROR_MIN + 2

// Object status flags
#define AFX_DAO_IMPLICIT_WS                     0x01
#define AFX_DAO_IMPLICIT_DB                     0x02
#define AFX_DAO_IMPLICIT_QD                     0x04
#define AFX_DAO_IMPLICIT_TD                     0x08
#define AFX_DAO_IMPLICIT_CLOSE                  0x40
#define AFX_DAO_DEFAULT_WS                      0x80

// CDaoRecordView status flags
#define AFX_DAOVIEW_SCROLL_NEXT                 0x01
#define AFX_DAOVIEW_SCROLL_LAST                 0x02
#define AFX_DAOVIEW_SCROLL_BACKWARD             0x04

// Logging helpers
void AFXAPI AfxDaoCheck(SCODE scode, LPCSTR lpszDaoCall,
	LPCSTR lpszFile, int nLine, int nError = NO_AFX_DAO_ERROR,
	BOOL bMemOnly = FALSE);

#ifdef _DEBUG
void AFXAPI AfxDaoTrace(SCODE scode, LPCSTR lpszDaoCall,
	LPCSTR lpszFile, int nLine);
#endif

#ifdef _DEBUG
#define DAO_CHECK(f)            AfxDaoCheck(f, #f, THIS_FILE, __LINE__)
#define DAO_CHECK_ERROR(f, err) AfxDaoCheck(f, #f, THIS_FILE, __LINE__, err)
#define DAO_CHECK_MEM(f)        AfxDaoCheck(f, #f, THIS_FILE, __LINE__, \
									NO_AFX_DAO_ERROR, TRUE)
#define DAO_TRACE(f)            AfxDaoTrace(f, #f, THIS_FILE, __LINE__)
#else
#define DAO_CHECK(f)            AfxDaoCheck(f, NULL, NULL, 0)
#define DAO_CHECK_ERROR(f, err) AfxDaoCheck(f, NULL, NULL, 0, err)
#define DAO_CHECK_MEM(f)        AfxDaoCheck(f, NULL, NULL, 0, \
									NO_AFX_DAO_ERROR, TRUE)
#define DAO_TRACE(f)            f
#endif

/////////////////////////////////////////////////////////////////////////////
// CDaoFieldExchange - for field exchange
class CDaoFieldExchange
{
// Attributes
public:
	enum DFX_Operation
	{
		AddToParameterList,     // builds PARAMETERS clause
		AddToSelectList,        // builds SELECT clause
		BindField,              // sets up binding structure
		BindParam,              // sets parameter values
		Fixup,                  // sets NULL status
		AllocCache,             // allocates cache used for dirty check
		StoreField,             // saves current record to cache
		LoadField,              // restores cached data to member vars
		FreeCache,              // frees cache
		SetFieldNull,           // sets field status & value to NULL
		MarkForAddNew,          // marks fields dirty if not PSEUDO NULL
		MarkForEdit,            // marks fields dirty if don't match cache
		SetDirtyField,          // sets field values marked as dirty
#ifdef _DEBUG
		DumpField,
#endif
		MaxDFXOperation,        // dummy operation type for input checking
	};

	UINT m_nOperation;          // type of exchange operation
	CDaoRecordset* m_prs;       // recordset handle

// Operations
public:
	enum FieldType
	{
		none,
		outputColumn,
		param,
	};

	void SetFieldType(UINT nFieldType);
	BOOL IsValidOperation();

// Implementation
public:
	CDaoFieldExchange(UINT nOperation, CDaoRecordset* prs,
		void* pvField = NULL);

	void Default(LPCTSTR lpszName, void* pv, DWORD dwFieldType,
		DWORD dwBindOptions = 0);

	static void PASCAL AppendParamType(CString& strParamList, DWORD dwParamType);
	static CDaoFieldCache* PASCAL GetCacheValue(CDaoRecordset* prs, void* pv);
	static void PASCAL SetNullValue(void* pv, DWORD dwDataType);
	static BOOL PASCAL IsNullValue(void* pv, DWORD dwDataType);
	static void PASCAL AllocCacheValue(CDaoFieldCache*& pCache, DWORD dwDataType);
	static void PASCAL DeleteCacheValue(CDaoFieldCache* pCache, DWORD dwDataType);
	static void PASCAL CopyValue(void* pvSrc, void* pvDest, DWORD dwDataType);
	static BOOL PASCAL CompareValue(void* pvSrc, void* pvDest, DWORD dwDataType);
	static void PASCAL FillVariant(void* pvValue, DWORD dwDataType, COleVariant** ppVar);

	// Current type of field
	UINT m_nFieldType;
	void* m_pvField;
	UINT m_nField;
	UINT m_nParam;
	UINT m_nFieldFound;

#ifdef _DEBUG
	CDumpContext* m_pdcDump;
#endif //_DEBUG
};

/////////////////////////////////////////////////////////////////////////////
// Standard RecordSet Field Exchange routines

// variable length data
void AFXAPI DFX_Text(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	CString& value, int nPreAllocSize = AFX_DAO_TEXT_DEFAULT_SIZE,
	DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);
void AFXAPI DFX_Binary(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	CByteArray& value, int nPreAllocSize = AFX_DAO_BINARY_DEFAULT_SIZE,
	DWORD dwBindOptions = 0);
void AFXAPI DFX_LongBinary(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	CLongBinary& value, DWORD dwPreAllocSize = AFX_DAO_LONGBINARY_DEFAULT_SIZE,
	DWORD dwBndOptions = 0);

//fixed length data
void AFXAPI DFX_Bool(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	BOOL& value, DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);
void AFXAPI DFX_Byte(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	BYTE& value, DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);
void AFXAPI DFX_Short(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	short& value, DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);
void AFXAPI DFX_Long(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	long& value, DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);
void AFXAPI DFX_Currency(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	COleCurrency& value, DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);
void AFXAPI DFX_Single(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	float& value, DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);
void AFXAPI DFX_Double(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	double& value, DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);
void AFXAPI DFX_DateTime(CDaoFieldExchange* pFX, LPCTSTR lpszName,
	COleDateTime& value, DWORD dwBindOptions = AFX_DAO_ENABLE_FIELD_CACHE);

//////////////////////////////////////////////////////////////////////////
// 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, BOOL& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, BYTE& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, short& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, long& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, COleCurrency& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, DWORD& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, float& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, double& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, COleDateTime& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldText(CDataExchange* pDX, int nIDC, CString& value,
	CDaoRecordset* pRecordset);

// special control types
void AFXAPI DDX_FieldCheck(CDataExchange* pDX, int nIDC, int& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldRadio(CDataExchange* pDX, int nIDC, int& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldLBString(CDataExchange* pDX, int nIDC,
	CString& value, CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldCBString(CDataExchange* pDX, int nIDC,
	CString& value, CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldLBStringExact(CDataExchange* pDX, int nIDC,
	CString& value, CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldCBStringExact(CDataExchange* pDX, int nIDC,
	CString& value, CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldLBIndex(CDataExchange* pDX, int nIDC, int& index,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldCBIndex(CDataExchange* pDX, int nIDC, int& index,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldLBStringExact(CDataExchange* pDX, int nIDC, CString& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldCBStringExact(CDataExchange* pDX, int nIDC, CString& value,
	CDaoRecordset* pRecordset);
void AFXAPI DDX_FieldScroll(CDataExchange* pDX, int nIDC, int& value,
	CDaoRecordset* pRecordset);

////////////////////////////////////////////////////////////////////////
// CDaoWorkspace - a DAO Workspace

class CDaoWorkspace : public CObject
{
	DECLARE_DYNAMIC(CDaoWorkspace)

// Constructors
public:
	CDaoWorkspace();

	virtual void Create(LPCTSTR lpszName, LPCTSTR lpszUserName,
		LPCTSTR lpszPassword);
	virtual void Append();

	virtual void Open(LPCTSTR lpszName = NULL);
	virtual void Close();

// Attributes
public:
	DAOWorkspace* m_pDAOWorkspace;

	static CString PASCAL GetVersion();
	static CString PASCAL GetIniPath();
	static void PASCAL SetIniPath(LPCTSTR lpszRegistrySubKey);
	static void PASCAL SetDefaultUser(LPCTSTR lpszDefaultUser);
	static void PASCAL SetDefaultPassword(LPCTSTR lpszPassword);
	static short PASCAL GetLoginTimeout();
	static void PASCAL SetLoginTimeout(short nSeconds);

	CString GetName();
	CString GetUserName();
	void SetIsolateODBCTrans(BOOL bIsolateODBCTrans);
	BOOL GetIsolateODBCTrans();

	BOOL IsOpen() const;

// Operations
public:
	void BeginTrans();
	void CommitTrans();
	void Rollback();

	static void PASCAL CompactDatabase(LPCTSTR lpszSrcName,
		LPCTSTR lpszDestName, LPCTSTR lpszLocale = dbLangGeneral,
		int nOptions = 0);
	// Password parameter added late in dev cycle, new interface req'd
	static void PASCAL CompactDatabase(LPCTSTR lpszSrcName,
		LPCTSTR lpszDestName, LPCTSTR lpszLocale, int nOptions,
		LPCTSTR lpszPassword);
	static void PASCAL RepairDatabase(LPCTSTR lpszName);

	static void PASCAL Idle(int nAction = dbFreeLocks);

	short GetWorkspaceCount();
	void GetWorkspaceInfo(int nIndex, CDaoWorkspaceInfo& wkspcinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetWorkspaceInfo(LPCTSTR lpszName, CDaoWorkspaceInfo& wkspcinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

	short GetDatabaseCount();
	void GetDatabaseInfo(int nIndex, CDaoDatabaseInfo& dbinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetDatabaseInfo(LPCTSTR lpszName, CDaoDatabaseInfo& dbinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

// Overridables
public:

// Implementation
public:
	virtual ~CDaoWorkspace();

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	DAOWorkspaces* m_pDAOWorkspaces;
	DAODatabases* m_pDAODatabases;
	int m_nStatus;

	CMapPtrToPtr m_mapDatabases;        // Map of all Open CDaoDatabases
	BOOL IsNew() const;

protected:
	BOOL m_bOpen;
	BOOL m_bNew;

	static void AFX_CDECL InitializeEngine();

	void InitWorkspacesCollection();
	void FillWorkspaceInfo(DAOWorkspace* pDAOWorkspace,
		CDaoWorkspaceInfo& wsinfo, DWORD dwOptions);

	void InitDatabasesCollection();
	void FillDatabaseInfo(DAODatabase* pDAODatabase,
		CDaoDatabaseInfo& dbinfo, DWORD dwOptions);

	virtual void ThrowDaoException(int nError = NO_AFX_DAO_ERROR);
};

////////////////////////////////////////////////////////////////////////
// CDaoException - DAO error trapping mechanism
class CDaoException : public CException
{
	DECLARE_DYNAMIC(CDaoException)

// Constructors
public:
	CDaoException();

// Attributes
public:
	CDaoErrorInfo* m_pErrorInfo;

	SCODE m_scode;
	int m_nAfxDaoError;     // DAO class extended error code

// Operations
public:
	short GetErrorCount();
	void GetErrorInfo(int nIndex);

// Implementation
public:
	virtual ~CDaoException();

	DAOError* m_pDAOError;
	DAOErrors* m_pDAOErrors;

	virtual BOOL GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
		PUINT pnHelpContext = NULL);

protected:
	void InitErrorsCollection();
	void FillErrorInfo();
};

void AFXAPI AfxThrowDaoException(int nAfxDaoError = NO_AFX_DAO_ERROR,
	SCODE scode = S_OK);


////////////////////////////////////////////////////////////////////////
// CDaoDatabase - a DAO Database

class CDaoDatabase : public CObject
{
	DECLARE_DYNAMIC(CDaoDatabase)

// Constructors
public:
	CDaoDatabase(CDaoWorkspace* pWorkspace = NULL);

	virtual void Create(LPCTSTR lpszName,
		LPCTSTR lpszLocale = dbLangGeneral, int dwOptions = 0);

	virtual void Open(LPCTSTR lpszName, BOOL bExclusive = FALSE,
		BOOL bReadOnly = FALSE, LPCTSTR lpszConnect = _T(""));
	virtual void Close();

// Attributes
public:
	CDaoWorkspace* m_pWorkspace;
	DAODatabase* m_pDAODatabase;

	BOOL IsOpen() const;

	BOOL CanUpdate();
	BOOL CanTransact();

	CString GetName();
	CString GetConnect();

	CString GetVersion();
	short GetQueryTimeout();
	void SetQueryTimeout(short nSeconds);
	long GetRecordsAffected();

// Operations
public:
	void Execute(LPCTSTR lpszSQL, int nOptions = dbFailOnError);

	void DeleteTableDef(LPCTSTR lpszName);
	void DeleteQueryDef(LPCTSTR lpszName);

	void CreateRelation(LPCTSTR lpszName, LPCTSTR lpszTable,
		LPCTSTR lpszForeignTable, long lAttributes,
		LPCTSTR lpszField, LPCTSTR lpszForeignField);
	void CreateRelation(CDaoRelationInfo& relinfo);
	void DeleteRelation(LPCTSTR lpszName);

	short GetTableDefCount();
	void GetTableDefInfo(int nIndex, CDaoTableDefInfo& tabledefinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetTableDefInfo(LPCTSTR lpszName, CDaoTableDefInfo& tabledefinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

	short GetRelationCount();
	void GetRelationInfo(int nIndex, CDaoRelationInfo& relinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetRelationInfo(LPCTSTR lpszName, CDaoRelationInfo& relinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

	short GetQueryDefCount();
	void GetQueryDefInfo(int nIndex, CDaoQueryDefInfo& querydefinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetQueryDefInfo(LPCTSTR lpszName, CDaoQueryDefInfo& querydefinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

// Overridables
public:

// Implementation
public:
	virtual ~CDaoDatabase();

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	DAOTableDefs* m_pDAOTableDefs;
	DAORelations* m_pDAORelations;
	DAOQueryDefs* m_pDAOQueryDefs;
	DAORecordsets* m_pDAORecordsets;
	int m_nStatus;

	CMapPtrToPtr m_mapTableDefs;        // Map of all Open CDaoTableDefs
	CMapPtrToPtr m_mapQueryDefs;        // Map of all Open CDaoQueryDefs
	CMapPtrToPtr m_mapRecordsets;       // Map of all Open CDaoRecordsets

protected:
	BOOL m_bOpen;

	void InitWorkspace();
	void InitTableDefsCollection();
	void FillTableDefInfo(DAOTableDef* pDAOTableDef,
		CDaoTableDefInfo& tabledefinfo, DWORD dwOptions);
	void InitRelationsCollection();
	void FillRelationInfo(DAORelation* pDAORelation,
		CDaoRelationInfo& relinfo, DWORD dwOptions);
	void InitQueryDefsCollection();
	void FillQueryDefInfo(DAOQueryDef* pDAOQueryDef,
		CDaoQueryDefInfo& querydefinfo, DWORD dwOptions);

	virtual void ThrowDaoException(int nError = NO_AFX_DAO_ERROR);
};


////////////////////////////////////////////////////////////////////////
// CDaoTableDef - a DAO TableDef

class CDaoTableDef : public CObject
{
	DECLARE_DYNAMIC(CDaoTableDef)

// Constructors
public:
	CDaoTableDef(CDaoDatabase* pDatabase);

	virtual void Create(LPCTSTR lpszName, long lAttributes = 0,
		LPCTSTR lpszSrcTable = NULL, LPCTSTR lpszConnect = NULL);
	virtual void Append();

	virtual void Open(LPCTSTR lpszName);
	virtual void Close();

// Attributes
public:
	CDaoDatabase* m_pDatabase;
	DAOTableDef* m_pDAOTableDef;

	BOOL IsOpen() const;
	BOOL CanUpdate();

	void SetName(LPCTSTR lpszName);
	CString GetName();
	void SetSourceTableName(LPCTSTR lpszSrcTableName);
	CString GetSourceTableName();
	void SetConnect(LPCTSTR lpszConnect);
	CString GetConnect();
	void SetAttributes(long lAttributes);
	long GetAttributes();
	COleDateTime GetDateCreated();
	COleDateTime GetDateLastUpdated();
	void SetValidationRule(LPCTSTR lpszValidationRule);
	CString GetValidationRule();
	void SetValidationText(LPCTSTR lpszValidationText);
	CString GetValidationText();
	long GetRecordCount();

// Overridables
public:

// Operations
public:
	void CreateField(LPCTSTR lpszName, short nType, long lSize,
		long lAttributes = 0);
	void CreateField(CDaoFieldInfo& fieldinfo);
	void DeleteField(LPCTSTR lpszName);
	void DeleteField(int nIndex);

	void CreateIndex(CDaoIndexInfo& indexinfo);
	void DeleteIndex(LPCTSTR lpszName);
	void DeleteIndex(int nIndex);

	short GetFieldCount();
	void GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetFieldInfo(LPCTSTR lpszName, CDaoFieldInfo& fieldinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

	short GetIndexCount();
	void GetIndexInfo(int nIndex, CDaoIndexInfo& indexinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetIndexInfo(LPCTSTR lpszName, CDaoIndexInfo& indexinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

	void RefreshLink();

// Implementation
public:
	~CDaoTableDef();

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	DAOFields* m_pDAOFields;
	DAOIndexes* m_pDAOIndexes;

protected:
	BOOL m_bOpen;
	BOOL m_bNew;

	void InitFieldsCollection();
	void InitIndexesCollection();

	virtual void ThrowDaoException(int nError = NO_AFX_DAO_ERROR);
};


////////////////////////////////////////////////////////////////////////
// CDaoQueryDef - a DAO QueryDef

class CDaoQueryDef : public CObject
{
	DECLARE_DYNAMIC(CDaoQueryDef)

// Constructors
public:
	CDaoQueryDef(CDaoDatabase* pDatabase);

	virtual void Create(LPCTSTR lpszName = NULL,
		LPCTSTR lpszSQL = NULL);
	virtual void Append();

	virtual void Open(LPCTSTR lpszName = NULL);
	virtual void Close();

// Attributes
public:
	CDaoDatabase* m_pDatabase;
	DAOQueryDef* m_pDAOQueryDef;

	BOOL CanUpdate();

	CString GetName();
	void SetName(LPCTSTR lpszName);
	CString GetSQL();
	void SetSQL(LPCTSTR lpszSQL);
	short GetType();
	COleDateTime GetDateCreated();
	COleDateTime GetDateLastUpdated();
	CString GetConnect();
	void SetConnect(LPCTSTR lpszConnect);
	short GetODBCTimeout();
	void SetODBCTimeout(short nODBCTimeout);
	BOOL GetReturnsRecords();
	void SetReturnsRecords(BOOL bReturnsRecords);
	long GetRecordsAffected();

	BOOL IsOpen() const;

// Operations
public:
	virtual void Execute(int nOptions = dbFailOnError);

	virtual COleVariant GetParamValue(LPCTSTR lpszName);
	virtual COleVariant GetParamValue(int nIndex);
	virtual void SetParamValue(LPCTSTR lpszName,
		const COleVariant& varValue);
	virtual void SetParamValue(int nIndex,
		const COleVariant& varValue);
	void SetParamValueNull(LPCTSTR lpszName);
	void SetParamValueNull(int nIndex);

	short GetFieldCount();
	void GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetFieldInfo(LPCTSTR lpszName, CDaoFieldInfo& fieldinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

	short GetParameterCount();
	void GetParameterInfo(int nIndex, CDaoParameterInfo& paraminfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetParameterInfo(LPCTSTR lpszName,
		CDaoParameterInfo& paraminfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

// Overridables
public:

// Implementation
public:
	~CDaoQueryDef();

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	DAOFields* m_pDAOFields;
	DAOParameters* m_pDAOParameters;

protected:
	BOOL m_bOpen;
	BOOL m_bNew;

	void InitFieldsCollection();
	void InitParametersCollection();
	void FillParameterInfo(DAOParameter* pDAOParameter,
		CDaoParameterInfo& paraminfo, DWORD dwInfoOptions);

	virtual void ThrowDaoException(int nError = NO_AFX_DAO_ERROR);
};


////////////////////////////////////////////////////////////////////////
// CDaoRecordset - the result of a query or base table browse

class CDaoRecordset : public CObject
{
	DECLARE_DYNAMIC(CDaoRecordset)

// Constructor
public:
	CDaoRecordset(CDaoDatabase* pDatabase = NULL);

	virtual void Open(int nOpenType = AFX_DAO_USE_DEFAULT_TYPE,
		LPCTSTR lpszSQL = NULL, int nOptions = 0);
	virtual void Open(CDaoQueryDef* pQueryDef,
		int nOpenType = dbOpenDynaset, int nOptions = 0);
	virtual void Open(CDaoTableDef* pTableDef,
		int nOpenType = dbOpenTable, int nOptions = 0);
	virtual void Close();

// Attributes
public:
	CDaoDatabase* m_pDatabase;  // Source database for this result set
	DAORecordset* m_pDAORecordset;

	CString m_strFilter;    // Filter string used when constructing SQL
	CString m_strSort;      // Sort string used when constructing SQL

	int m_nFields;
	int m_nParams;

	BOOL m_bCheckCacheForDirtyFields;   // Switch for dirty field checking.

	BOOL CanUpdate() const;
	BOOL CanAppend() const;
	BOOL CanScroll() const;
	BOOL CanRestart();
	BOOL CanTransact();
	BOOL CanBookmark();

	BOOL IsOpen() const;
	BOOL IsBOF();
	BOOL IsEOF();
	BOOL IsDeleted() const;

	BOOL IsFieldDirty(void* pv);
	BOOL IsFieldNull(void* pv);
	BOOL IsFieldNullable(void* pv);

	CString GetName();
	short GetType();
	short GetEditMode();
	CString GetSQL() const;

	COleDateTime GetDateCreated();
	COleDateTime GetDateLastUpdated();
	COleVariant GetLastModifiedBookmark();
	CString GetValidationRule();
	CString GetValidationText();
	CString GetCurrentIndex();
	void SetCurrentIndex(LPCTSTR lpszIndex);

	long GetRecordCount();

// Operations
public:
	// Cursor operations
	void MoveNext();
	void MovePrev();
	void MoveFirst();
	void MoveLast();
	virtual void Move(long lRows);

	BOOL FindNext(LPCTSTR lpszFilter);
	BOOL FindPrev(LPCTSTR lpszFilter);
	BOOL FindFirst(LPCTSTR lpszFilter);
	BOOL FindLast(LPCTSTR lpszFilter);
	virtual BOOL Find(long lFindType, LPCTSTR lpszFilter);

	COleVariant GetBookmark();
	void SetBookmark(COleVariant varBookmark);
	long GetAbsolutePosition();
	void SetAbsolutePosition(long lPosition);
	float GetPercentPosition();
	void SetPercentPosition(float fPosition);

	// seek allowed on recordset opened as tables (max keys = 13)
	BOOL Seek(LPCTSTR lpszComparison, COleVariant* pKey1,
		COleVariant* pKey2 = NULL, COleVariant* pKey3 = NULL);
	BOOL Seek(LPCTSTR lpszComparison, COleVariant* pKeyArray, WORD nKeys);

	// edit buffer operations
	virtual void AddNew();
	virtual void Edit();
	virtual void Update();
	virtual void Delete();
	virtual void CancelUpdate();

	// field operations
	virtual void GetFieldValue(LPCTSTR lpszName, COleVariant& varValue);
	virtual void GetFieldValue(int nIndex, COleVariant& varValue);
	virtual void SetFieldValue(LPCTSTR lpszName,
		const COleVariant& varValue);
	virtual void SetFieldValue(int nIndex,
		const COleVariant& varValue);
	void SetFieldValue(int nIndex, LPCTSTR lpszValue);
	void SetFieldValue(LPCTSTR lpszName, LPCTSTR lpszValue);
	void SetFieldValueNull(LPCTSTR lpszName);
	void SetFieldValueNull(int nIndex);

	virtual COleVariant GetParamValue(LPCTSTR lpszName);
	virtual COleVariant GetParamValue(int nIndex);
	virtual void SetParamValue(LPCTSTR lpszName,
		const COleVariant& varValue);
	virtual void SetParamValue(int nIndex,
		const COleVariant& varValue);
	void SetParamValueNull(LPCTSTR lpszName);
	void SetParamValueNull(int nIndex);

	void SetFieldDirty(void* pv, BOOL bDirty = TRUE);
	void SetFieldNull(void* pv, BOOL bNull = TRUE);

	void SetLockingMode(BOOL bPessimistic);
	BOOL GetLockingMode();

	// Recordset operations
	virtual void Requery();

	// Jet's remote data caching operations
	void SetCacheStart(COleVariant varBookmark);
	COleVariant GetCacheStart();
	void SetCacheSize(long lSize);
	long GetCacheSize();
	void FillCache(long* pSize = NULL, COleVariant* pBookmark = NULL);

	short GetFieldCount();
	void GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetFieldInfo(LPCTSTR lpszName, CDaoFieldInfo& fieldinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

	short GetIndexCount();
	void GetIndexInfo(int nIndex, CDaoIndexInfo& indexinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
	void GetIndexInfo(LPCTSTR lpszName, CDaoIndexInfo& indexinfo,
		DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

// Overridables
public:
	virtual CString GetDefaultDBName();
	virtual CString GetDefaultSQL();

	// for recordset field exchange
	virtual void DoFieldExchange(CDaoFieldExchange* pFX);

// Implementation
public:
	virtual ~CDaoRecordset();

	// Out-of-date functions kept for backward compatability
	virtual COleVariant GetFieldValue(LPCTSTR lpszName);
	virtual COleVariant GetFieldValue(int nIndex);

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	CString m_strSQL;

	CDaoQueryDef* m_pQueryDef;  // Source query for this result set
	CDaoTableDef* m_pTableDef;
	ICDAORecordset* m_pICDAORecordsetGetRows;
	DAOFields* m_pDAOFields;
	DAOIndexes* m_pDAOIndexes;

	void SetCursorAttributes();
	void GetDataAndFixupNulls();
	DWORD GetFieldLength(int nFieldIndex);

	BOOL IsFieldStatusDirty(UINT nField);
	void SetDirtyFieldStatus(UINT nField);
	void ClearDirtyFieldStatus(UINT nField);

	BOOL IsFieldStatusNull(UINT nField);
	void SetNullFieldStatus(UINT nField);
	void ClearNullFieldStatus(UINT nField);

	BOOL IsFieldStatusNullable(UINT nField);
	void SetNullableFieldStatus(UINT nField);

	BOOL IsFieldStatusNullableKnown(UINT nField);
	void SetNullableKnownFieldStatus(UINT nField);

	void ClearFieldStatusFlags();
	BOOL IsMatch();

	DWORD m_cbFixedLengthFields;
	DAOCOLUMNBINDING* m_prgDaoColBindInfo;
	DWORD* m_pulColumnLengths;
	DAOFETCHROWS m_DaoFetchRows;
	BYTE* m_pbFieldFlags;
	BYTE* m_pbParamFlags;

	CMapPtrToPtr* m_pMapFieldCache;
	CMapPtrToPtr* m_pMapFieldIndex;

	static void AFX_CDECL StripBrackets(LPCTSTR lpszSrc, LPTSTR lpszDest);

protected:
	BOOL m_bOpen;
	int m_nStatus;

	BOOL m_bAppendable;
	BOOL m_bScrollable;
	BOOL m_bDeleted;

	int m_nOpenType;
	int m_nDefaultType;
	int m_nOptions;

	CString m_strRequerySQL;
	CString m_strRequeryFilter;
	CString m_strRequerySort;

	void BuildSQL();
	void AllocDatabase();

	// RFX Operation Cover Functions
	void BuildSelectList();
	void BuildParameterList();
	void BindFields();
	void BindParameters();
	void Fixup();
	void AllocCache();
	void StoreFields();
	void LoadFields();
	void FreeCache();
	void MarkForEdit();
	void MarkForAddNew();
	int GetFieldIndex(void* pv);
	virtual void SetDirtyFields();

	void InitFieldsCollection();
	void InitIndexesCollection();

	virtual void ThrowDaoException(int nError = NO_AFX_DAO_ERROR);

	friend class CDaoFieldExchange;
	friend class CDaoRecordView;
};

/////////////////////////////////////////////////////////////////////////////
// CDaoRecordView - form for viewing data records

class CDaoRecordView : public CFormView
{
	DECLARE_DYNAMIC(CDaoRecordView)

// Construction
protected:  // must derive your own class
	CDaoRecordView(LPCTSTR lpszTemplateName);
	CDaoRecordView(UINT nIDTemplate);

// Attributes
public:
	virtual CDaoRecordset* OnGetRecordset() = 0;

	BOOL IsOnLastRecord();
	BOOL IsOnFirstRecord();

// Operations
public:
	virtual BOOL OnMove(UINT nIDMoveCommand);

// Implementation
public:
	virtual ~CDaoRecordView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif
	virtual void OnInitialUpdate();

protected:
	int m_nStatus;
	COleVariant m_varBookmarkCurrent;
	COleVariant m_varBookmarkFirst;
	COleVariant m_varBookmarkLast;

	//{{AFX_MSG(CDaoRecordView)
	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()
};

/////////////////////////////////////////////////////////////////////////////
// DAODBEngine helpers - implementation specific and undocumented
void AFXAPI AfxDaoInit();
DAODBEngine* AFXAPI AfxDaoGetEngine();
void AFXAPI AfxDaoTerm();

/////////////////////////////////////////////////////////////////////////////
// Inline function declarations

#ifdef _AFX_PACKING
#pragma pack(pop)
#endif

#ifdef _AFX_ENABLE_INLINES
#define _AFXDAOCORE_INLINE inline
#define _AFXDAODFX_INLINE inline
#define _AFXDAOVIEW_INLINE inline
#include <afxdao.inl>
#undef _AFXDAOCORE_INLINE
#undef _AFXDAODFX_INLINE
#undef _AFXDAOVIEW_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 //__AFXDAO_H__

/////////////////////////////////////////////////////////////////////////////