mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5753 lines
123 KiB
5753 lines
123 KiB
// 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.
|
|
|
|
#include "stdafx.h"
|
|
|
|
#ifdef AFX_DB_SEG
|
|
#pragma code_seg(AFX_DB_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Maintain DAODBEngine object
|
|
|
|
_AFX_DAO_STATE::_AFX_DAO_STATE()
|
|
{
|
|
m_pDAODBEngine = NULL;
|
|
m_bOleInitialized = FALSE;
|
|
}
|
|
|
|
_AFX_DAO_STATE::~_AFX_DAO_STATE()
|
|
{
|
|
ASSERT(m_mapWorkspaces.IsEmpty());
|
|
ASSERT(m_pDAODBEngine == NULL);
|
|
ASSERT(!m_bOleInitialized);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Helpers
|
|
|
|
// Index function return value
|
|
#define AFX_DAO_DATA_NOT_FOUND (-1L)
|
|
|
|
#define AFX_DAO_FETCH_PRIMARY_PROPERTIES \
|
|
(AFX_DAO_PRIMARY_INFO | AFX_DAO_SECONDARY_INFO | AFX_DAO_ALL_INFO)
|
|
#define AFX_DAO_FETCH_SECONDARY_PROPERTIES \
|
|
(AFX_DAO_SECONDARY_INFO | AFX_DAO_ALL_INFO)
|
|
#define AFX_DAO_FETCH_ALL_PROPERTIES \
|
|
AFX_DAO_ALL_INFO
|
|
|
|
// Info helpers
|
|
void AFX_CDECL AfxGetFieldInfo(DAOField* pDAOField, CDaoFieldInfo& fieldinfo,
|
|
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
|
|
void AFX_CDECL AfxSetFieldInfo(DAOField* pDAOField, CDaoFieldInfo& fieldinfo);
|
|
void AFX_CDECL AfxGetIndexInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo,
|
|
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
|
|
void AFX_CDECL AfxSetIndexInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo);
|
|
void AFX_CDECL AfxGetIndexFields(DAOIndex* pDAOIndex,
|
|
DAOIndexFields** ppDAOIndexFields);
|
|
void AFX_CDECL AfxGetIndexFieldInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo);
|
|
void AFX_CDECL AfxSetIndexFieldInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo);
|
|
|
|
// GetRows helper
|
|
void AFX_CDECL ThrowGetRowsDaoException(SCODE scode);
|
|
|
|
// _AFX_DAO_STATE helper
|
|
_AFX_DAO_STATE* AFX_CDECL AfxGetDaoState();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Global data
|
|
|
|
static const TCHAR szParameters[] = _T("PARAMETERS ");
|
|
static const TCHAR szSelect[] = _T("SELECT ");
|
|
static const TCHAR szFrom[] = _T(" FROM ");
|
|
static const TCHAR szWhere[] = _T(" WHERE ");
|
|
static const TCHAR szOrderBy[] = _T(" ORDER BY ");
|
|
static const TCHAR szTransform[] = _T("TRANSFORM ");
|
|
static const TCHAR szTable[] = _T("TABLE ");
|
|
|
|
// Need a static VARIANT for optional DAO parameters
|
|
static VARIANT _afxOptionalVariant;
|
|
|
|
struct AFX_INITOPTIONALVARIANT
|
|
{
|
|
AFX_INITOPTIONALVARIANT()
|
|
{
|
|
_afxOptionalVariant.vt = VT_ERROR;
|
|
_afxOptionalVariant.scode = DISP_E_PARAMNOTFOUND;
|
|
};
|
|
};
|
|
|
|
static const AFX_INITOPTIONALVARIANT _afxInitOptionalVariant;
|
|
|
|
// Need a static VARIANT for NULL DAO parameters
|
|
static VARIANT _afxNullVariant;
|
|
|
|
struct AFX_INITNULLVARIANT
|
|
{
|
|
AFX_INITNULLVARIANT()
|
|
{
|
|
_afxNullVariant.vt = VT_NULL;
|
|
};
|
|
};
|
|
|
|
static const AFX_INITNULLVARIANT _afxInitNullVariant;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Logging helpers
|
|
|
|
void AFXAPI AfxDaoCheck(SCODE scode, LPCSTR lpszDaoCall,
|
|
LPCSTR lpszFile, int nLine, int nError, BOOL bMemOnly)
|
|
{
|
|
UNUSED(lpszDaoCall);
|
|
UNUSED(lpszFile);
|
|
UNUSED(nLine);
|
|
|
|
if (FAILED(scode))
|
|
{
|
|
#ifdef _DEBUG
|
|
if (afxTraceFlags & traceDatabase)
|
|
{
|
|
TRACE0("\nDAO Call Failed.");
|
|
TRACE1("\n\t%hs", lpszDaoCall);
|
|
TRACE2("\n\tIn file %hs on line %d", lpszFile, nLine);
|
|
TRACE1("\n\tscode = %X\n", scode);
|
|
}
|
|
#endif
|
|
if (scode == E_OUTOFMEMORY)
|
|
AfxThrowMemoryException();
|
|
else if (!bMemOnly)
|
|
AfxThrowDaoException(nError, scode);
|
|
}
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void AFXAPI AfxDaoTrace(SCODE scode, LPCSTR lpszDaoCall,
|
|
LPCSTR lpszFile, int nLine)
|
|
{
|
|
if (FAILED(scode))
|
|
{
|
|
if (afxTraceFlags & traceDatabase)
|
|
{
|
|
TRACE0("\nDAO Call Failed.\n\t");
|
|
TRACE1("\n%hs", lpszDaoCall);
|
|
TRACE2("\nIn file %hs on line %d\n", lpszFile, nLine);
|
|
TRACE1("scode = %X\n", scode);
|
|
}
|
|
}
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Info structure diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoErrorInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoErrorInfo at " << (void*)this;
|
|
|
|
dc << "\nm_lErrorCode = " << m_lErrorCode;
|
|
dc << "\nm_strSource = " << m_strSource;
|
|
dc << "\nm_strDescription = " << m_strDescription;
|
|
dc << "\nm_strHelpFile = " << m_strHelpFile;
|
|
dc << "\nm_lHelpContext = " << m_lHelpContext;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoWorkspaceInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoWorkspaceInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_strUserName = " << m_strUserName;
|
|
dc << "\nb = m_bIsolateODBCTrans" << m_bIsolateODBCTrans;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoDatabaseInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoDatabaseInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_bUpdatable = " << m_bUpdatable;
|
|
dc << "\nm_bTransactions = " << m_bTransactions;
|
|
dc << "\nm_strVersion = " << m_strVersion;
|
|
dc << "\nm_lCollatingOrder = " << m_lCollatingOrder;
|
|
dc << "\nm_nQueryTimeout = " << m_nQueryTimeout;
|
|
dc << "\nm_strConnect = " << m_strConnect;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoTableDefInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoTableDefInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_bUpdatable = " << m_bUpdatable;
|
|
dc << "\nm_lAttributes = " << m_lAttributes;
|
|
dc << "\nm_dateDateCreated = " << m_dateCreated;
|
|
dc << "\nm_dateLastUpdated = " << m_dateLastUpdated;
|
|
dc << "\nm_strSrcTableName = " << m_strSrcTableName;
|
|
dc << "\nm_strConnect = " << m_strConnect;
|
|
dc << "\nm_strValidationRule = " << m_strValidationRule;
|
|
dc << "\nm_strValidationText = " << m_strValidationText;
|
|
dc << "\nm_lRecordCount = " << m_lRecordCount;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoFieldInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoFieldInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_nType = " << m_nType;
|
|
dc << "\nm_lSize = " << m_lSize;
|
|
dc << "\nm_lAttributes = " << m_lAttributes;
|
|
dc << "\nm_nOrdinalPosition = " << m_nOrdinalPosition;
|
|
dc << "\nm_bRequired = " << m_bRequired;
|
|
dc << "\nm_bAllowZeroLength = " << m_bAllowZeroLength;
|
|
dc << "\nm_lCollatingOrder = " << m_lCollatingOrder;
|
|
dc << "\nm_strForeignName = " << m_strForeignName;
|
|
dc << "\nm_strSourceField = " << m_strSourceField;
|
|
dc << "\nm_strSourceTable = " << m_strSourceTable;
|
|
dc << "\nm_strValidationRule = " << m_strValidationRule;
|
|
dc << "\nm_strValidationText = " << m_strValidationText;
|
|
dc << "\nm_strDefaultValue = " << m_strDefaultValue;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoIndexFieldInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << " a CDaoIndexFieldInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_bDescending = " << m_bDescending;
|
|
}
|
|
#endif
|
|
|
|
CDaoIndexInfo::CDaoIndexInfo()
|
|
{
|
|
m_pFieldInfos = NULL;
|
|
m_nFields = 0;
|
|
m_bCleanupFieldInfo = FALSE;
|
|
}
|
|
|
|
CDaoIndexInfo::~CDaoIndexInfo()
|
|
{
|
|
if (m_bCleanupFieldInfo && m_pFieldInfos != NULL)
|
|
{
|
|
delete[] m_pFieldInfos;
|
|
m_pFieldInfos = NULL;
|
|
}
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoIndexInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoIndexInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_nFields = " << m_nFields;
|
|
|
|
for (int nIndex = 0; nIndex < m_nFields; nIndex++)
|
|
m_pFieldInfos[nIndex].Dump(dc);
|
|
|
|
dc << "\nm_bPrimary = " << m_bPrimary;
|
|
dc << "\nm_bUnique = " << m_bUnique;
|
|
dc << "\nm_bClustered = " << m_bClustered;
|
|
dc << "\nm_bIgnoreNulls = " << m_bIgnoreNulls;
|
|
dc << "\nm_bRequired = " << m_bRequired;
|
|
dc << "\nm_bForeign = " << m_bForeign;
|
|
dc << "\nm_lDistinctCount = " << m_lDistinctCount;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoRelationFieldInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << " a CDaoRelationFieldInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_strForeignName = " << m_strForeignName;
|
|
}
|
|
#endif
|
|
|
|
CDaoRelationInfo::CDaoRelationInfo()
|
|
{
|
|
m_pFieldInfos = NULL;
|
|
m_nFields = 0;
|
|
m_bCleanupFieldInfo = FALSE;
|
|
}
|
|
|
|
CDaoRelationInfo::~CDaoRelationInfo()
|
|
{
|
|
if (m_bCleanupFieldInfo && m_pFieldInfos != NULL)
|
|
{
|
|
delete[] m_pFieldInfos;
|
|
m_pFieldInfos = NULL;
|
|
}
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoRelationInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoRelationInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_strTable = " << m_strTable;
|
|
dc << "\nm_strForeignTable = " << m_strForeignTable;
|
|
dc << "\nm_lAttributes = " << m_lAttributes;
|
|
dc << "\nm_nFields = " << m_nFields;
|
|
|
|
for (int nIndex = 0; nIndex < m_nFields; nIndex++)
|
|
m_pFieldInfos[nIndex].Dump(dc);
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoQueryDefInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoQueryDefInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_nType = " << m_nType;
|
|
dc << "\nm_dateCreated = " << m_dateCreated;
|
|
dc << "\nm_dateLastUpdated = " << m_dateLastUpdated;
|
|
dc << "\nm_bUpdatable = " << m_bUpdatable;
|
|
dc << "\nm_bReturnsRecords = " << m_bReturnsRecords;
|
|
dc << "\nm_strSQL = " << m_strSQL;
|
|
dc << "\nm_strConnect = " << m_strConnect;
|
|
dc << "\nm_nODBCTimeout = " << m_nODBCTimeout;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoParameterInfo::Dump(CDumpContext& dc) const
|
|
{
|
|
dc << "a CDaoParameterInfo at " << (void*)this;
|
|
|
|
dc << "\nm_strName = " << m_strName;
|
|
dc << "\nm_nType = " << m_nType;
|
|
dc << "\nm_varValue = " << m_varValue;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CDaoException
|
|
IMPLEMENT_DYNAMIC(CDaoException, CException)
|
|
|
|
CDaoException::CDaoException()
|
|
{
|
|
m_pDAOError = NULL;
|
|
m_pDAOErrors = NULL;
|
|
m_pErrorInfo = NULL;
|
|
}
|
|
|
|
CDaoException::~CDaoException()
|
|
{
|
|
delete m_pErrorInfo;
|
|
m_pErrorInfo = NULL;
|
|
|
|
if (m_pDAOErrors != NULL)
|
|
{
|
|
m_pDAOErrors->Release();
|
|
m_pDAOErrors = NULL;
|
|
}
|
|
|
|
if (m_pDAOError != NULL)
|
|
{
|
|
m_pDAOError->Release();
|
|
m_pDAOError = NULL;
|
|
}
|
|
}
|
|
|
|
// Operations
|
|
short CDaoException::GetErrorCount()
|
|
{
|
|
short nErrors = 1;
|
|
|
|
if (m_pDAOErrors == NULL)
|
|
InitErrorsCollection();
|
|
|
|
if (m_nAfxDaoError != AFX_DAO_ERROR_ENGINE_INITIALIZATION)
|
|
DAO_CHECK_MEM(m_pDAOErrors->get_Count(&nErrors));
|
|
|
|
return nErrors;
|
|
}
|
|
|
|
void CDaoException::GetErrorInfo(int nIndex)
|
|
{
|
|
ASSERT(m_pDAOError == NULL);
|
|
|
|
if (m_pDAOErrors == NULL)
|
|
InitErrorsCollection();
|
|
|
|
if (m_nAfxDaoError != AFX_DAO_ERROR_ENGINE_INITIALIZATION)
|
|
{
|
|
// Get DAOError object and fill in error info struct
|
|
DAO_CHECK_MEM(m_pDAOErrors->get_Item(
|
|
COleVariant((long)nIndex), &m_pDAOError));
|
|
|
|
FillErrorInfo();
|
|
|
|
// Clean up
|
|
m_pDAOError->Release();
|
|
m_pDAOError = NULL;
|
|
}
|
|
}
|
|
|
|
BOOL CDaoException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
|
|
PUINT pnHelpContext)
|
|
{
|
|
ASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
|
|
|
|
BOOL bRetCode = FALSE;
|
|
|
|
if (m_pErrorInfo != NULL)
|
|
{
|
|
// DAO help context is not a UINT!
|
|
// According to DAO it is positive and should be less 10,000,000
|
|
if (pnHelpContext != NULL)
|
|
*pnHelpContext = (UINT) m_pErrorInfo->m_lHelpContext;
|
|
|
|
lstrcpyn(lpszError, m_pErrorInfo->m_strDescription, nMaxError-1);
|
|
lpszError[nMaxError-1] = '\0';
|
|
bRetCode = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Must be MFC DAO class internal error, get error string
|
|
CString strError;
|
|
if (strError.LoadString(
|
|
AFX_IDP_DAO_FIRST + (m_nAfxDaoError - AFX_DAO_ERROR_MIN)))
|
|
{
|
|
lstrcpyn(lpszError, strError, nMaxError-1);
|
|
bRetCode = TRUE;
|
|
}
|
|
else
|
|
ASSERT(FALSE); // Couldn't get resource.
|
|
}
|
|
return bRetCode;
|
|
}
|
|
|
|
// Implementation
|
|
void CDaoException::InitErrorsCollection()
|
|
{
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
|
|
// Engine not initialized!
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
m_nAfxDaoError = AFX_DAO_ERROR_ENGINE_INITIALIZATION;
|
|
else
|
|
DAO_CHECK_MEM(pDaoState->m_pDAODBEngine->get_Errors(
|
|
&m_pDAOErrors));
|
|
}
|
|
|
|
void CDaoException::FillErrorInfo()
|
|
{
|
|
ASSERT(m_pDAOError != NULL);
|
|
// Allocate the error info structure if necessary
|
|
if (m_pErrorInfo == NULL)
|
|
m_pErrorInfo = new CDaoErrorInfo;
|
|
|
|
COleVariant var;
|
|
|
|
DAO_CHECK_MEM(m_pDAOError->get_Number(
|
|
&m_pErrorInfo->m_lErrorCode));
|
|
|
|
DAO_CHECK_MEM(m_pDAOError->get_Source(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
m_pErrorInfo->m_strSource = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK_MEM(m_pDAOError->get_Description(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
m_pErrorInfo->m_strDescription = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK_MEM(m_pDAOError->get_HelpFile(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
m_pErrorInfo->m_strHelpFile = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK_MEM(m_pDAOError->get_HelpContext(
|
|
&m_pErrorInfo->m_lHelpContext));
|
|
}
|
|
|
|
void AFXAPI AfxThrowDaoException(int nAfxDaoError, SCODE scode)
|
|
{
|
|
CDaoException* pException;
|
|
pException = new CDaoException;
|
|
|
|
pException->m_scode = scode;
|
|
|
|
if (nAfxDaoError == NO_AFX_DAO_ERROR)
|
|
{
|
|
TRY
|
|
{
|
|
int nErrors = pException->GetErrorCount();
|
|
for (int nIndex = 0; nIndex < nErrors; nIndex++)
|
|
{
|
|
pException->GetErrorInfo(nIndex);
|
|
#ifdef _DEBUG
|
|
if (afxTraceFlags & traceDatabase)
|
|
{
|
|
TRACE1("\nError Code = %d\n",
|
|
pException->m_pErrorInfo->m_lErrorCode);
|
|
TRACE1("Source = %s\n",
|
|
(LPCTSTR)pException->m_pErrorInfo->m_strSource);
|
|
TRACE1("Description = %s\n",
|
|
(LPCTSTR)pException->m_pErrorInfo->m_strDescription);
|
|
}
|
|
#endif // _DEBUG
|
|
}
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// No DAO error info
|
|
e->Delete();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
else
|
|
pException->m_nAfxDaoError = nAfxDaoError;
|
|
|
|
THROW(pException);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CDaoWorkspace
|
|
IMPLEMENT_DYNAMIC(CDaoWorkspace, CObject)
|
|
|
|
CDaoWorkspace::CDaoWorkspace()
|
|
{
|
|
m_pDAOWorkspaces = NULL;
|
|
m_pDAOWorkspace = NULL;
|
|
m_pDAODatabases = NULL;
|
|
|
|
m_bOpen = FALSE;
|
|
m_bNew = FALSE;
|
|
m_nStatus = 0;
|
|
}
|
|
|
|
CDaoWorkspace::~CDaoWorkspace()
|
|
{
|
|
if (IsOpen())
|
|
{
|
|
m_nStatus |= AFX_DAO_IMPLICIT_CLOSE;
|
|
Close();
|
|
}
|
|
else if (m_bNew)
|
|
{
|
|
// Remove the workspace from the AFX_DAO_STATE's map
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
pDaoState->m_mapWorkspaces.RemoveKey(this);
|
|
}
|
|
}
|
|
|
|
void CDaoWorkspace::Create(LPCTSTR lpszName, LPCTSTR lpszUserName,
|
|
LPCTSTR lpszPassword)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(!IsOpen());
|
|
ASSERT(lpszUserName != NULL);
|
|
ASSERT(lpszPassword != NULL);
|
|
|
|
// Get the DAODBEngine interface and initialize if necessary
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
COleVariant varName(lpszName, VT_BSTRT);
|
|
COleVariant varUserName(lpszUserName, VT_BSTRT);
|
|
COleVariant varPassword(lpszPassword, VT_BSTRT);
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->CreateWorkspace(
|
|
V_BSTR(&varName), V_BSTR(&varUserName),
|
|
V_BSTR(&varPassword), &m_pDAOWorkspace));
|
|
|
|
m_bNew = TRUE;
|
|
|
|
// Add the workspace to map of Open/New CDaoWorkspaces
|
|
pDaoState->m_mapWorkspaces.SetAt(this, this);
|
|
}
|
|
|
|
void CDaoWorkspace::Append()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_bNew);
|
|
ASSERT(m_pDAOWorkspace != NULL);
|
|
|
|
DAOWorkspaces* pDAOWorkspaces;
|
|
|
|
// Get the DAODBEngine interface and initialize if necessary
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->get_Workspaces(&pDAOWorkspaces));
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(pDAOWorkspaces->Append(m_pDAOWorkspace));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
pDAOWorkspaces->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOWorkspaces->Release();
|
|
|
|
m_bNew = FALSE;
|
|
m_bOpen = TRUE;
|
|
}
|
|
|
|
void CDaoWorkspace::Open(LPCTSTR lpszWorkspaceName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pDAOWorkspaces == NULL);
|
|
ASSERT(m_pDAOWorkspace == NULL);
|
|
|
|
// Re-Opening is invalid.
|
|
if (IsOpen())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
// Set the workspace name (or use 0 if opening default)
|
|
COleVariant var(lpszWorkspaceName, VT_BSTRT);
|
|
if (lpszWorkspaceName == NULL)
|
|
{
|
|
var = 0L;
|
|
|
|
// Set status to prevent DAO Workspace Close call
|
|
m_nStatus |= AFX_DAO_DEFAULT_WS;
|
|
}
|
|
|
|
// Get the DAODBEngine interface and initialize if necessary
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
// Get the workspace from the workspaces collection
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->get_Workspaces(
|
|
&m_pDAOWorkspaces));
|
|
DAO_CHECK(m_pDAOWorkspaces->get_Item(var, &m_pDAOWorkspace));
|
|
|
|
m_bOpen = TRUE;
|
|
m_pDAOWorkspaces->Release();
|
|
m_pDAOWorkspaces = NULL;
|
|
|
|
// Add the workspace to map of Open/New CDaoWorkspaces
|
|
pDaoState->m_mapWorkspaces.SetAt(this, this);
|
|
}
|
|
|
|
void CDaoWorkspace::Close()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAODatabases != NULL)
|
|
{
|
|
m_pDAODatabases->Release();
|
|
m_pDAODatabases = NULL;
|
|
}
|
|
|
|
// Close any Open CDaoDatabases
|
|
void* pvKey;
|
|
void* pvObject;
|
|
POSITION pos = m_mapDatabases.GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
m_mapDatabases.GetNextAssoc(pos, pvKey, pvObject);
|
|
((CDaoDatabase*)pvObject)->Close();
|
|
}
|
|
m_mapDatabases.RemoveAll();
|
|
|
|
if (m_pDAOWorkspace != NULL)
|
|
{
|
|
// If implicit workspace or close, don't call DAO close.
|
|
// It will be automatically closed when ref count 0.
|
|
if (!(m_nStatus & (AFX_DAO_IMPLICIT_WS | AFX_DAO_IMPLICIT_CLOSE |
|
|
AFX_DAO_DEFAULT_WS)))
|
|
{
|
|
DAO_TRACE(m_pDAOWorkspace->Close());
|
|
}
|
|
|
|
m_pDAOWorkspace->Release();
|
|
m_pDAOWorkspace = NULL;
|
|
}
|
|
|
|
if (m_pDAOWorkspaces != NULL)
|
|
{
|
|
m_pDAOWorkspaces->Release();
|
|
m_pDAOWorkspaces = NULL;
|
|
}
|
|
|
|
m_bOpen = FALSE;
|
|
m_bNew = FALSE;
|
|
m_nStatus &= ~AFX_DAO_DEFAULT_WS;
|
|
|
|
// Remove the workspace from the AFX_DAO_STATE's map
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
pDaoState->m_mapWorkspaces.RemoveKey(this);
|
|
}
|
|
|
|
CString PASCAL CDaoWorkspace::GetVersion()
|
|
{
|
|
COleVariant var;
|
|
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->get_Version(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
CString PASCAL CDaoWorkspace::GetIniPath()
|
|
{
|
|
COleVariant var;
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->get_IniPath(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void PASCAL CDaoWorkspace::SetIniPath(LPCTSTR lpszRegistrySubKey)
|
|
{
|
|
COleVariant var(lpszRegistrySubKey, VT_BSTRT);
|
|
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->put_IniPath(V_BSTR(&var)));
|
|
}
|
|
|
|
void PASCAL CDaoWorkspace::SetDefaultUser(LPCTSTR lpszDefaultUser)
|
|
{
|
|
COleVariant var(lpszDefaultUser, VT_BSTRT);
|
|
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->put_DefaultUser(V_BSTR(&var)));
|
|
}
|
|
|
|
void PASCAL CDaoWorkspace::SetDefaultPassword(LPCTSTR lpszPassword)
|
|
{
|
|
COleVariant var(lpszPassword, VT_BSTRT);
|
|
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->put_DefaultPassword(
|
|
V_BSTR(&var)));
|
|
}
|
|
|
|
short PASCAL CDaoWorkspace::GetLoginTimeout()
|
|
{
|
|
short nSeconds;
|
|
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->get_LoginTimeout(&nSeconds));
|
|
return nSeconds;
|
|
}
|
|
|
|
void PASCAL CDaoWorkspace::SetLoginTimeout(short nSeconds)
|
|
{
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->put_LoginTimeout(nSeconds));
|
|
}
|
|
|
|
|
|
CString CDaoWorkspace::GetName()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pDAOWorkspace != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOWorkspace->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
CString CDaoWorkspace::GetUserName()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pDAOWorkspace != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOWorkspace->get_UserName(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoWorkspace::SetIsolateODBCTrans(BOOL bIsolateODBCTrans)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pDAOWorkspace != NULL);
|
|
|
|
DAO_CHECK(m_pDAOWorkspace->put_IsolateODBCTrans(
|
|
(short)(bIsolateODBCTrans ? AFX_DAO_TRUE : AFX_DAO_FALSE)));
|
|
}
|
|
|
|
BOOL CDaoWorkspace::GetIsolateODBCTrans()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pDAOWorkspace != NULL);
|
|
|
|
short nIsolateODBCTrans;
|
|
DAO_CHECK(m_pDAOWorkspace->get_IsolateODBCTrans(&nIsolateODBCTrans));
|
|
return nIsolateODBCTrans == AFX_DAO_TRUE;
|
|
}
|
|
|
|
void PASCAL CDaoWorkspace::CompactDatabase(LPCTSTR lpszSrcName,
|
|
LPCTSTR lpszDestName, LPCTSTR lpszLocale, int nOptions,
|
|
LPCTSTR lpszPassword)
|
|
{
|
|
COleVariant varSrcName(lpszSrcName, VT_BSTRT);
|
|
COleVariant varDestName(lpszDestName, VT_BSTRT);
|
|
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->CompactDatabase(
|
|
V_BSTR(&varSrcName), V_BSTR(&varDestName),
|
|
COleVariant(lpszLocale, VT_BSTRT), COleVariant((long)nOptions),
|
|
lpszPassword != NULL ? (VARIANT)COleVariant(lpszPassword, VT_BSTRT) :
|
|
_afxOptionalVariant));
|
|
}
|
|
|
|
void PASCAL CDaoWorkspace::CompactDatabase(LPCTSTR lpszSrcName,
|
|
LPCTSTR lpszDestName, LPCTSTR lpszLocale, int nOptions)
|
|
{
|
|
CompactDatabase(lpszSrcName, lpszDestName, lpszLocale, nOptions, NULL);
|
|
}
|
|
|
|
void PASCAL CDaoWorkspace::RepairDatabase(LPCTSTR lpszName)
|
|
{
|
|
COleVariant varName(lpszName, VT_BSTRT);
|
|
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->RepairDatabase(
|
|
V_BSTR(&varName)));
|
|
}
|
|
|
|
void PASCAL CDaoWorkspace::Idle(int nAction)
|
|
{
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->Idle(
|
|
COleVariant((long)nAction)));
|
|
}
|
|
|
|
short CDaoWorkspace::GetWorkspaceCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nFields;
|
|
|
|
if (m_pDAOWorkspaces == NULL)
|
|
InitWorkspacesCollection();
|
|
|
|
DAO_CHECK(m_pDAOWorkspaces->get_Count(&nFields));
|
|
return nFields;
|
|
}
|
|
|
|
void CDaoWorkspace::GetWorkspaceInfo(int nIndex,
|
|
CDaoWorkspaceInfo& wsinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOWorkspaces == NULL)
|
|
InitWorkspacesCollection();
|
|
|
|
// Get DAOWorkspace object and fill in workspace info struct
|
|
DAOWorkspace* pDAOWorkspace;
|
|
DAO_CHECK(m_pDAOWorkspaces->get_Item(
|
|
COleVariant((long)nIndex), &pDAOWorkspace));
|
|
FillWorkspaceInfo(pDAOWorkspace, wsinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOWorkspace->Release();
|
|
}
|
|
|
|
void CDaoWorkspace::GetWorkspaceInfo(
|
|
LPCTSTR lpszName, CDaoWorkspaceInfo& wsinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOWorkspaces == NULL)
|
|
InitWorkspacesCollection();
|
|
|
|
// Get DAOWorkspace object and fill in workspace info struct
|
|
DAOWorkspace* pDAOWorkspace;
|
|
DAO_CHECK(m_pDAOWorkspaces->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOWorkspace));
|
|
FillWorkspaceInfo(pDAOWorkspace, wsinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOWorkspace->Release();
|
|
}
|
|
|
|
short CDaoWorkspace::GetDatabaseCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAODatabases == NULL)
|
|
InitDatabasesCollection();
|
|
|
|
short nFields;
|
|
DAO_CHECK(m_pDAODatabases->get_Count(&nFields));
|
|
return nFields;
|
|
}
|
|
|
|
void CDaoWorkspace::GetDatabaseInfo(int nIndex, CDaoDatabaseInfo& dbinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAODatabases == NULL)
|
|
InitDatabasesCollection();
|
|
|
|
// Get DAODatabase object and fill in database info struct
|
|
DAODatabase* pDAODatabase;
|
|
DAO_CHECK(m_pDAODatabases->get_Item(
|
|
COleVariant((long)nIndex), &pDAODatabase));
|
|
FillDatabaseInfo(pDAODatabase, dbinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAODatabase->Release();
|
|
}
|
|
|
|
void CDaoWorkspace::GetDatabaseInfo(LPCTSTR lpszName,
|
|
CDaoDatabaseInfo& dbinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAODatabases == NULL)
|
|
InitDatabasesCollection();
|
|
|
|
// Get DAODatabase object and fill in database info struct
|
|
DAODatabase* pDAODatabase;
|
|
DAO_CHECK(m_pDAODatabases->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAODatabase));
|
|
FillDatabaseInfo(pDAODatabase, dbinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAODatabase->Release();
|
|
}
|
|
|
|
void CDaoWorkspace::BeginTrans()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOWorkspace != NULL);
|
|
|
|
DAO_CHECK(m_pDAOWorkspace->BeginTrans());
|
|
}
|
|
|
|
void CDaoWorkspace::CommitTrans()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOWorkspace != NULL);
|
|
|
|
DAO_CHECK(m_pDAOWorkspace->CommitTrans());
|
|
}
|
|
|
|
void CDaoWorkspace::Rollback()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOWorkspace != NULL);
|
|
|
|
DAO_CHECK(m_pDAOWorkspace->Rollback());
|
|
}
|
|
|
|
//Implementation
|
|
void AFX_CDECL CDaoWorkspace::InitializeEngine()
|
|
{
|
|
AfxDaoInit();
|
|
}
|
|
|
|
void CDaoWorkspace::InitWorkspacesCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
if (pDaoState->m_pDAODBEngine == NULL)
|
|
InitializeEngine();
|
|
|
|
DAO_CHECK(pDaoState->m_pDAODBEngine->get_Workspaces(
|
|
&m_pDAOWorkspaces));
|
|
}
|
|
|
|
void CDaoWorkspace::FillWorkspaceInfo(DAOWorkspace* pDAOWorkspace,
|
|
CDaoWorkspaceInfo& wsinfo, DWORD dwOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(pDAOWorkspace != NULL);
|
|
ASSERT(dwOptions != 0);
|
|
|
|
COleVariant var;
|
|
short nBool;
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOWorkspace->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
wsinfo.m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
}
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOWorkspace->get_UserName(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
wsinfo.m_strUserName = V_BSTRT(&var);
|
|
var.Clear();
|
|
}
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOWorkspace->get_IsolateODBCTrans(&nBool));
|
|
wsinfo.m_bIsolateODBCTrans = nBool == AFX_DAO_TRUE;
|
|
}
|
|
}
|
|
|
|
void CDaoWorkspace::InitDatabasesCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAO_CHECK(m_pDAOWorkspace->get_Databases(&m_pDAODatabases));
|
|
}
|
|
|
|
void CDaoWorkspace::FillDatabaseInfo(DAODatabase* pDAODatabase,
|
|
CDaoDatabaseInfo& dbinfo, DWORD dwOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(pDAODatabase != NULL);
|
|
ASSERT(dwOptions != 0);
|
|
|
|
COleVariant var;
|
|
short nBool;
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAODatabase->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
dbinfo.m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAODatabase->get_Updatable(&nBool));
|
|
dbinfo.m_bUpdatable = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAODatabase->get_Transactions(&nBool));
|
|
dbinfo.m_bTransactions = nBool == AFX_DAO_TRUE;
|
|
}
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAODatabase->get_Version(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
dbinfo.m_strVersion = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAODatabase->get_CollatingOrder(
|
|
&dbinfo.m_lCollatingOrder));
|
|
|
|
DAO_CHECK(pDAODatabase->get_QueryTimeout(
|
|
&dbinfo.m_nQueryTimeout));
|
|
}
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAODatabase->get_Connect(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
dbinfo.m_strConnect = V_BSTRT(&var);
|
|
var.Clear();
|
|
}
|
|
}
|
|
|
|
void CDaoWorkspace::ThrowDaoException(int nAfxDaoError)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AfxThrowDaoException(nAfxDaoError);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoWorkspace::AssertValid() const
|
|
{
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
void CDaoWorkspace::Dump(CDumpContext& dc) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CObject::Dump(dc);
|
|
|
|
dc << "m_bOpen = " << m_bOpen;
|
|
dc << "\nm_bNew = " << m_bNew;
|
|
dc << "\nm_nStatus = " << m_nStatus;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CDaoDatabase
|
|
IMPLEMENT_DYNAMIC(CDaoDatabase, CObject)
|
|
|
|
CDaoDatabase::CDaoDatabase(CDaoWorkspace* pWorkspace)
|
|
{
|
|
m_bOpen = FALSE;
|
|
|
|
m_pDAODatabase = NULL;
|
|
|
|
m_pDAOTableDefs = NULL;
|
|
m_pDAORelations = NULL;
|
|
m_pDAOQueryDefs = NULL;
|
|
m_pDAORecordsets = NULL;
|
|
|
|
m_pWorkspace = pWorkspace;
|
|
m_nStatus = 0;
|
|
}
|
|
|
|
CDaoDatabase::~CDaoDatabase()
|
|
{
|
|
if (IsOpen())
|
|
Close();
|
|
|
|
// Clean up workspace if necessary
|
|
if (m_pWorkspace != NULL && (m_nStatus & AFX_DAO_IMPLICIT_WS))
|
|
{
|
|
m_pWorkspace->Close();
|
|
delete m_pWorkspace;
|
|
m_pWorkspace = NULL;
|
|
}
|
|
}
|
|
|
|
void CDaoDatabase::Create(LPCTSTR lpszName, LPCTSTR lpszLocale,
|
|
int nOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(!IsOpen());
|
|
|
|
// Allocate and maintain workspace if necessary
|
|
InitWorkspace();
|
|
|
|
COleVariant varName(lpszName, VT_BSTRT);
|
|
COleVariant varLocale(lpszLocale, VT_BSTRT);
|
|
|
|
DAO_CHECK(m_pWorkspace->m_pDAOWorkspace->CreateDatabase(V_BSTR(&varName),
|
|
V_BSTR(&varLocale), COleVariant((long)nOptions),
|
|
&m_pDAODatabase));
|
|
|
|
m_bOpen = TRUE;
|
|
|
|
// Add the database to map of Open CDaoDatabases
|
|
m_pWorkspace->m_mapDatabases.SetAt(this, this);
|
|
}
|
|
|
|
void CDaoDatabase::Open(LPCTSTR lpszName, BOOL bExclusive,
|
|
BOOL bReadOnly, LPCTSTR lpszConnect)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Re-Opening is invalid.
|
|
if (IsOpen())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
// Allocate, maintain and/or open workspace if necessary
|
|
InitWorkspace();
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
|
|
DAO_CHECK(m_pWorkspace->m_pDAOWorkspace->OpenDatabase(
|
|
V_BSTR(&var),
|
|
COleVariant((long)bExclusive, VT_BOOL),
|
|
COleVariant((long)bReadOnly, VT_BOOL),
|
|
COleVariant(lpszConnect, VT_BSTRT),
|
|
&m_pDAODatabase));
|
|
|
|
m_bOpen = TRUE;
|
|
|
|
// Add the database to map of Open CDaoDatabases
|
|
m_pWorkspace->m_mapDatabases.SetAt(this, this);
|
|
}
|
|
|
|
// Disconnect connection
|
|
void CDaoDatabase::Close()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAORecordsets != NULL)
|
|
{
|
|
m_pDAORecordsets->Release();
|
|
m_pDAORecordsets = NULL;
|
|
}
|
|
|
|
if (m_pDAOQueryDefs != NULL)
|
|
{
|
|
m_pDAOQueryDefs->Release();
|
|
m_pDAOQueryDefs = NULL;
|
|
}
|
|
|
|
if (m_pDAORelations != NULL)
|
|
{
|
|
m_pDAORelations->Release();
|
|
m_pDAORelations = NULL;
|
|
}
|
|
|
|
if (m_pDAOTableDefs != NULL)
|
|
{
|
|
m_pDAOTableDefs->Release();
|
|
m_pDAOTableDefs = NULL;
|
|
}
|
|
|
|
// Close any Open CDaoRecordsets
|
|
void* pvKey;
|
|
void* pvObject;
|
|
POSITION pos = m_mapRecordsets.GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
m_mapRecordsets.GetNextAssoc(pos, pvKey, pvObject);
|
|
((CDaoRecordset*)pvObject)->Close();
|
|
}
|
|
m_mapRecordsets.RemoveAll();
|
|
|
|
// Close any Open CDaoQueryDefs
|
|
pos = m_mapQueryDefs.GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
m_mapQueryDefs.GetNextAssoc(pos, pvKey, pvObject);
|
|
((CDaoQueryDef*)pvObject)->Close();
|
|
}
|
|
m_mapQueryDefs.RemoveAll();
|
|
|
|
// Close any Open CDaoTableDefs
|
|
pos = m_mapTableDefs.GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
m_mapTableDefs.GetNextAssoc(pos, pvKey, pvObject);
|
|
((CDaoTableDef*)pvObject)->Close();
|
|
}
|
|
m_mapTableDefs.RemoveAll();
|
|
|
|
if (m_pDAODatabase != NULL)
|
|
{
|
|
// If implicit database, don't close.
|
|
// It will be automatically closed when ref count 0.
|
|
if (!(m_nStatus & AFX_DAO_IMPLICIT_DB))
|
|
DAO_TRACE(m_pDAODatabase->Close());
|
|
|
|
m_pDAODatabase->Release();
|
|
m_pDAODatabase = NULL;
|
|
}
|
|
|
|
m_bOpen = FALSE;
|
|
|
|
// Remove the CDaoDatabase from the CDaoWorkspace's map
|
|
m_pWorkspace->m_mapDatabases.RemoveKey(this);
|
|
}
|
|
|
|
BOOL CDaoDatabase::CanUpdate()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
short nUpdatable;
|
|
DAO_CHECK(m_pDAODatabase->get_Updatable(&nUpdatable));
|
|
return nUpdatable == AFX_DAO_TRUE;
|
|
}
|
|
|
|
BOOL CDaoDatabase::CanTransact()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
short nTransactable;
|
|
DAO_CHECK(m_pDAODatabase->get_Transactions(&nTransactable));
|
|
return nTransactable == AFX_DAO_TRUE;
|
|
}
|
|
|
|
CString CDaoDatabase::GetName()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAODatabase->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
CString CDaoDatabase::GetConnect()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAODatabase->get_Connect(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
CString CDaoDatabase::GetVersion()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAODatabase->get_Version(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
short CDaoDatabase::GetQueryTimeout()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
short nQueryTimeout;
|
|
DAO_CHECK(m_pDAODatabase->get_QueryTimeout(&nQueryTimeout));
|
|
return nQueryTimeout;
|
|
}
|
|
|
|
void CDaoDatabase::SetQueryTimeout(short nSeconds)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
DAO_CHECK(m_pDAODatabase->put_QueryTimeout(nSeconds));
|
|
}
|
|
|
|
long CDaoDatabase::GetRecordsAffected()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
long lRecordsAffected;
|
|
DAO_CHECK(m_pDAODatabase->get_RecordsAffected(&lRecordsAffected));
|
|
return lRecordsAffected;
|
|
}
|
|
|
|
void CDaoDatabase::DeleteTableDef(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
if (m_pDAOTableDefs == NULL)
|
|
InitTableDefsCollection();
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOTableDefs->Delete(V_BSTR(&var)));
|
|
}
|
|
|
|
void CDaoDatabase::DeleteQueryDef(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
if (m_pDAOQueryDefs == NULL)
|
|
InitQueryDefsCollection();
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOQueryDefs->Delete(V_BSTR(&var)));
|
|
}
|
|
|
|
void CDaoDatabase::CreateRelation(LPCTSTR lpszName, LPCTSTR lpszTable,
|
|
LPCTSTR lpszForeignTable, long lAttributes, LPCTSTR lpszField,
|
|
LPCTSTR lpszForeignField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CDaoRelationInfo relinfo;
|
|
CDaoRelationFieldInfo fieldinfo;
|
|
|
|
relinfo.m_strName = lpszName;
|
|
relinfo.m_strTable = lpszTable;
|
|
relinfo.m_strForeignTable = lpszForeignTable;
|
|
relinfo.m_lAttributes = lAttributes;
|
|
relinfo.m_nFields = 1;
|
|
|
|
relinfo.m_pFieldInfos = &fieldinfo;
|
|
relinfo.m_pFieldInfos->m_strName = lpszField;
|
|
relinfo.m_pFieldInfos->m_strForeignName = lpszForeignField;
|
|
|
|
CreateRelation(relinfo);
|
|
}
|
|
|
|
void CDaoDatabase::CreateRelation(CDaoRelationInfo& relinfo)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(relinfo.m_nFields > 0);
|
|
|
|
// Initialize relations collection so that relation can be appended later
|
|
if (m_pDAORelations == NULL)
|
|
InitRelationsCollection();
|
|
|
|
DAORelation* pDAORelation = NULL;
|
|
DAOFields* pDAOFields = NULL;
|
|
DAOField* pDAOField = NULL;
|
|
|
|
// Create the relation
|
|
DAO_CHECK(m_pDAODatabase->CreateRelation(
|
|
COleVariant(relinfo.m_strName, VT_BSTRT),
|
|
COleVariant(relinfo.m_strTable, VT_BSTRT),
|
|
COleVariant(relinfo.m_strForeignTable, VT_BSTRT),
|
|
COleVariant(relinfo.m_lAttributes), &pDAORelation));
|
|
|
|
TRY
|
|
{
|
|
// Get the fields collection for later append of created field
|
|
DAO_CHECK(pDAORelation->get_Fields(&pDAOFields));
|
|
|
|
// Create field(s) and set the name and foreign name
|
|
for (int nIndex = 0; nIndex < relinfo.m_nFields; nIndex++)
|
|
{
|
|
DAO_CHECK(pDAORelation->CreateField(
|
|
COleVariant(relinfo.m_pFieldInfos[nIndex].m_strName, VT_BSTRT),
|
|
_afxOptionalVariant, _afxOptionalVariant, &pDAOField));
|
|
|
|
COleVariant var(relinfo.m_pFieldInfos[nIndex].m_strForeignName, VT_BSTRT);
|
|
DAO_CHECK(pDAOField->put_ForeignName(V_BSTR(&var)));
|
|
|
|
// Append the field to relation fields collection and release
|
|
DAO_CHECK(pDAOFields->Append(pDAOField));
|
|
pDAOField->Release();
|
|
}
|
|
|
|
DAO_CHECK(m_pDAORelations->Append(pDAORelation));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Clean up before throw
|
|
if (pDAOField != NULL)
|
|
pDAOField->Release();
|
|
|
|
if (pDAOFields != NULL)
|
|
pDAOFields->Release();
|
|
|
|
pDAORelation->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
// Clean up
|
|
if (pDAOField != NULL)
|
|
pDAOField->Release();
|
|
|
|
pDAOFields->Release();
|
|
pDAORelation->Release();
|
|
}
|
|
|
|
void CDaoDatabase::DeleteRelation(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
if (m_pDAORelations == NULL)
|
|
InitRelationsCollection();
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAORelations->Delete(V_BSTR(&var)));
|
|
}
|
|
|
|
void CDaoDatabase::Execute(LPCTSTR lpszSQL, int nOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pDAODatabase != NULL);
|
|
|
|
COleVariant var(lpszSQL, VT_BSTRT);
|
|
DAO_CHECK(m_pDAODatabase->Execute(
|
|
V_BSTR(&var), COleVariant((long)nOptions)));
|
|
}
|
|
|
|
short CDaoDatabase::GetTableDefCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nTables;
|
|
|
|
if (m_pDAOTableDefs == NULL)
|
|
InitTableDefsCollection();
|
|
|
|
DAO_CHECK(m_pDAOTableDefs->get_Count(&nTables));
|
|
return nTables;
|
|
}
|
|
|
|
void CDaoDatabase::GetTableDefInfo(int nIndex, CDaoTableDefInfo& tabledefinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOTableDefs == NULL)
|
|
InitTableDefsCollection();
|
|
|
|
// Get DAOTableDef object and fill in table info struct
|
|
DAOTableDef* pDAOTableDef;
|
|
DAO_CHECK(m_pDAOTableDefs->get_Item(
|
|
COleVariant((long)nIndex), &pDAOTableDef));
|
|
FillTableDefInfo(pDAOTableDef, tabledefinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOTableDef->Release();
|
|
}
|
|
|
|
void CDaoDatabase::GetTableDefInfo(LPCTSTR lpszName,
|
|
CDaoTableDefInfo& tabledefinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOTableDefs == NULL)
|
|
InitTableDefsCollection();
|
|
|
|
// Get DAOTableDef object and fill in table info struct
|
|
DAOTableDef* pDAOTableDef;
|
|
DAO_CHECK(m_pDAOTableDefs->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOTableDef));
|
|
FillTableDefInfo(pDAOTableDef, tabledefinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOTableDef->Release();
|
|
}
|
|
|
|
short CDaoDatabase::GetRelationCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nRelations;
|
|
|
|
if (m_pDAORelations == NULL)
|
|
InitRelationsCollection();
|
|
|
|
DAO_CHECK(m_pDAORelations->get_Count(&nRelations));
|
|
return nRelations;
|
|
}
|
|
|
|
void CDaoDatabase::GetRelationInfo(int nIndex, CDaoRelationInfo& relinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAORelations == NULL)
|
|
InitRelationsCollection();
|
|
|
|
// Get DAORelation object and fill in relation info struct
|
|
DAORelation* pDAORelation;
|
|
DAO_CHECK(m_pDAORelations->get_Item(
|
|
COleVariant((long)nIndex), &pDAORelation));
|
|
FillRelationInfo(pDAORelation, relinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAORelation->Release();
|
|
}
|
|
|
|
void CDaoDatabase::GetRelationInfo(LPCTSTR lpszName,
|
|
CDaoRelationInfo& relinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAORelations == NULL)
|
|
InitRelationsCollection();
|
|
|
|
// Get DAORelation object and fill in relation info struct
|
|
DAORelation* pDAORelation;
|
|
DAO_CHECK(m_pDAORelations->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAORelation));
|
|
FillRelationInfo(pDAORelation, relinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAORelation->Release();
|
|
}
|
|
|
|
short CDaoDatabase::GetQueryDefCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nQueryDefs;
|
|
|
|
if (m_pDAOQueryDefs == NULL)
|
|
InitQueryDefsCollection();
|
|
|
|
DAO_CHECK(m_pDAOQueryDefs->get_Count(&nQueryDefs));
|
|
return nQueryDefs;
|
|
}
|
|
|
|
void CDaoDatabase::GetQueryDefInfo(int nIndex, CDaoQueryDefInfo& querydefinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOQueryDefs == NULL)
|
|
InitQueryDefsCollection();
|
|
|
|
// Get DAOQueryDef object and fill in query info struct
|
|
DAOQueryDef* pDAOQueryDef;
|
|
DAO_CHECK(m_pDAOQueryDefs->get_Item(
|
|
COleVariant((long)nIndex), &pDAOQueryDef));
|
|
FillQueryDefInfo(pDAOQueryDef, querydefinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOQueryDef->Release();
|
|
}
|
|
|
|
void CDaoDatabase::GetQueryDefInfo(LPCTSTR lpszName,
|
|
CDaoQueryDefInfo& querydefinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOQueryDefs == NULL)
|
|
InitQueryDefsCollection();
|
|
|
|
// Get DAOQueryDef object and fill in query info struct
|
|
DAOQueryDef* pDAOQueryDef;
|
|
DAO_CHECK(m_pDAOQueryDefs->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOQueryDef));
|
|
FillQueryDefInfo(pDAOQueryDef, querydefinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOQueryDef->Release();
|
|
}
|
|
|
|
// Implementation
|
|
void CDaoDatabase::InitWorkspace()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pWorkspace == NULL)
|
|
{
|
|
// Allocate workspace and mark as implicit
|
|
m_pWorkspace = new CDaoWorkspace;
|
|
m_pWorkspace->m_nStatus |= AFX_DAO_IMPLICIT_WS;
|
|
m_nStatus |= AFX_DAO_IMPLICIT_WS;
|
|
}
|
|
|
|
// Open workspace if not open and not new (unappended)
|
|
if (!m_pWorkspace->IsOpen() && !m_pWorkspace->IsNew())
|
|
{
|
|
// Open the default workspace
|
|
m_pWorkspace->Open();
|
|
}
|
|
}
|
|
|
|
void CDaoDatabase::InitTableDefsCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAO_CHECK(m_pDAODatabase->get_TableDefs(&m_pDAOTableDefs));
|
|
}
|
|
|
|
void CDaoDatabase::FillTableDefInfo(DAOTableDef* pDAOTableDef,
|
|
CDaoTableDefInfo& tabledefinfo, DWORD dwOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(pDAOTableDef != NULL);
|
|
ASSERT(dwOptions != 0);
|
|
|
|
COleVariant var;
|
|
short nBool;
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOTableDef->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
tabledefinfo.m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOTableDef->get_Updatable(&nBool));
|
|
tabledefinfo.m_bUpdatable = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOTableDef->get_Attributes(
|
|
&tabledefinfo.m_lAttributes));
|
|
}
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOTableDef->get_DateCreated(&var));
|
|
tabledefinfo.m_dateCreated = var;
|
|
|
|
DAO_CHECK(pDAOTableDef->get_LastUpdated(&var));
|
|
tabledefinfo.m_dateLastUpdated = var;
|
|
|
|
DAO_CHECK(pDAOTableDef->get_SourceTableName(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
tabledefinfo.m_strSrcTableName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOTableDef->get_Connect(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
tabledefinfo.m_strConnect = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOTableDef->get_ValidationRule(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
tabledefinfo.m_strValidationRule = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOTableDef->get_ValidationText(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
tabledefinfo.m_strValidationText = V_BSTRT(&var);
|
|
var.Clear();
|
|
}
|
|
|
|
// This may be expensive, so only get it if absolutely necessary
|
|
if (dwOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOTableDef->get_RecordCount(
|
|
&tabledefinfo.m_lRecordCount));
|
|
}
|
|
}
|
|
|
|
void CDaoDatabase::InitRelationsCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAO_CHECK(m_pDAODatabase->get_Relations(&m_pDAORelations));
|
|
}
|
|
|
|
void CDaoDatabase::FillRelationInfo(DAORelation* pDAORelation,
|
|
CDaoRelationInfo& relinfo, DWORD dwOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(pDAORelation != NULL);
|
|
ASSERT(dwOptions != 0);
|
|
|
|
COleVariant var;
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
|
|
{
|
|
// All the relation info is primary
|
|
DAO_CHECK(pDAORelation->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
relinfo.m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAORelation->get_Table(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
relinfo.m_strTable = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAORelation->get_ForeignTable(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
relinfo.m_strForeignTable = V_BSTRT(&var);
|
|
var.Clear();
|
|
}
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
|
|
{
|
|
DAOFields* pDAOFields = NULL;
|
|
DAOField* pDAOField = NULL;
|
|
|
|
DAO_CHECK(pDAORelation->get_Attributes(
|
|
&relinfo.m_lAttributes));
|
|
|
|
// Get the fields collection
|
|
DAO_CHECK(pDAORelation->get_Fields(&pDAOFields));
|
|
|
|
TRY
|
|
{
|
|
// Get the number of fields in the relation
|
|
short nCount;
|
|
DAO_CHECK(pDAOFields->get_Count(&nCount));
|
|
|
|
// Allocate or reallocate memory for array if necessary
|
|
if (nCount != relinfo.m_nFields)
|
|
{
|
|
if (relinfo.m_nFields != 0)
|
|
{
|
|
// Check that allocation is correct.
|
|
ASSERT(relinfo.m_nFields == 0 ||
|
|
relinfo.m_bCleanupFieldInfo);
|
|
|
|
delete[] relinfo.m_pFieldInfos;
|
|
relinfo.m_pFieldInfos = NULL;
|
|
}
|
|
|
|
// Now allocate required memory
|
|
relinfo.m_pFieldInfos = new CDaoRelationFieldInfo[nCount];
|
|
relinfo.m_bCleanupFieldInfo = TRUE;
|
|
relinfo.m_nFields = nCount;
|
|
}
|
|
|
|
// Now get field info for each field
|
|
for (int nIndex = 0; nIndex < relinfo.m_nFields; nIndex++)
|
|
{
|
|
// Get the field item
|
|
DAO_CHECK(pDAOFields->get_Item(
|
|
COleVariant((long)nIndex), &pDAOField));
|
|
|
|
// Get the field name
|
|
DAO_CHECK(pDAOField->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
relinfo.m_pFieldInfos[nIndex].m_strName =
|
|
V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
// Get the foreign field name
|
|
DAO_CHECK(pDAOField->get_ForeignName(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
relinfo.m_pFieldInfos[nIndex].m_strForeignName =
|
|
V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
// Release and reset the field object
|
|
pDAOField->Release();
|
|
pDAOField = NULL;
|
|
}
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pDAOField != NULL)
|
|
pDAOField->Release();
|
|
|
|
pDAOFields->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
// Release the objects
|
|
pDAOFields->Release();
|
|
}
|
|
}
|
|
|
|
void CDaoDatabase::InitQueryDefsCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAO_CHECK(m_pDAODatabase->get_QueryDefs(&m_pDAOQueryDefs));
|
|
}
|
|
|
|
void CDaoDatabase::FillQueryDefInfo(DAOQueryDef* pDAOQueryDef,
|
|
CDaoQueryDefInfo& querydefinfo, DWORD dwOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(pDAOQueryDef != NULL);
|
|
ASSERT(dwOptions != 0);
|
|
|
|
COleVariant var;
|
|
short nBool;
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOQueryDef->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
querydefinfo.m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOQueryDef->get_Type(&querydefinfo.m_nType));
|
|
}
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOQueryDef->get_Updatable(&nBool));
|
|
querydefinfo.m_bUpdatable = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOQueryDef->get_DateCreated(&var));
|
|
querydefinfo.m_dateCreated = var;
|
|
|
|
DAO_CHECK(pDAOQueryDef->get_LastUpdated(&var));
|
|
querydefinfo.m_dateLastUpdated = var;
|
|
|
|
DAO_CHECK(pDAOQueryDef->get_ReturnsRecords(&nBool));
|
|
querydefinfo.m_bReturnsRecords = nBool == AFX_DAO_TRUE;
|
|
}
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOQueryDef->get_SQL(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
querydefinfo.m_strSQL = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOQueryDef->get_Connect(&V_BSTR(
|
|
(LPVARIANT)var)));
|
|
var.vt = VT_BSTR;
|
|
querydefinfo.m_strConnect = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
// DAO will display ODBC connect dialog
|
|
// if data source no longer exists. This must
|
|
// be avoided during bulk info retrieval.
|
|
// Call CDaoQueryDef::GetODBCTimeout directly.
|
|
// DAO_CHECK(pDAOQueryDef->get_ODBCTimeout(
|
|
// &querydefinfo.m_nODBCTimeout));
|
|
|
|
// Set the m_nODBCTimeout variable to invalid value.
|
|
querydefinfo.m_nODBCTimeout = -1;
|
|
}
|
|
}
|
|
|
|
void CDaoDatabase::ThrowDaoException(int nAfxDaoError)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AfxThrowDaoException(nAfxDaoError);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoDatabase::AssertValid() const
|
|
{
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
void CDaoDatabase::Dump(CDumpContext& dc) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CObject::Dump(dc);
|
|
|
|
dc << "m_bOpen = " << m_bOpen;
|
|
dc << "\nm_nStatus = " << m_nStatus;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CDaoTableDef
|
|
IMPLEMENT_DYNAMIC(CDaoTableDef, CObject)
|
|
|
|
CDaoTableDef::CDaoTableDef(CDaoDatabase* pDatabase)
|
|
{
|
|
m_bOpen = FALSE;
|
|
m_bNew = FALSE;
|
|
|
|
m_pDatabase = pDatabase;
|
|
m_pDAOTableDef = NULL;
|
|
m_pDAOFields = NULL;
|
|
m_pDAOIndexes = NULL;
|
|
}
|
|
|
|
CDaoTableDef::~CDaoTableDef()
|
|
{
|
|
if (IsOpen())
|
|
Close();
|
|
else if (m_bNew)
|
|
{
|
|
// Remove the tabledef from the CDaoDatabase's map
|
|
m_pDatabase->m_mapTableDefs.RemoveKey(this);
|
|
}
|
|
}
|
|
|
|
void CDaoTableDef::Create(LPCTSTR lpszName, long lAttributes,
|
|
LPCTSTR lpszSrcTable, LPCTSTR lpszConnect)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(!IsOpen());
|
|
|
|
DAO_CHECK(m_pDatabase->m_pDAODatabase->CreateTableDef(
|
|
COleVariant(lpszName, VT_BSTRT), COleVariant(lAttributes),
|
|
COleVariant(lpszSrcTable, VT_BSTRT),
|
|
COleVariant(lpszConnect, VT_BSTRT), &m_pDAOTableDef));
|
|
|
|
m_bNew = TRUE;
|
|
|
|
// Add the tabledef to map of Open/New CDaoTableDefs
|
|
m_pDatabase->m_mapTableDefs.SetAt(this, this);
|
|
}
|
|
|
|
void CDaoTableDef::Append()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_bNew);
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
DAOTableDefs* pDAOTableDefs;
|
|
DAO_CHECK(m_pDatabase->m_pDAODatabase->get_TableDefs(
|
|
&pDAOTableDefs));
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(pDAOTableDefs->Append(m_pDAOTableDef));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
pDAOTableDefs->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOTableDefs->Release();
|
|
|
|
m_bNew = FALSE;
|
|
m_bOpen = TRUE;
|
|
}
|
|
|
|
void CDaoTableDef::Open(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(lpszName != NULL);
|
|
|
|
// Re-open is invalid
|
|
if (IsOpen())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
DAOTableDefs* pDAOTableDefs = NULL;
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(m_pDatabase->m_pDAODatabase->get_TableDefs(
|
|
&pDAOTableDefs));
|
|
DAO_CHECK(pDAOTableDefs->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT),&m_pDAOTableDef));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pDAOTableDefs != NULL)
|
|
pDAOTableDefs->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOTableDefs->Release();
|
|
|
|
m_bOpen = TRUE;
|
|
|
|
// Add the tabledef to map of Open/New CDaoTableDefs
|
|
m_pDatabase->m_mapTableDefs.SetAt(this, this);
|
|
}
|
|
|
|
void CDaoTableDef::Close()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOIndexes != NULL)
|
|
{
|
|
m_pDAOIndexes->Release();
|
|
m_pDAOIndexes = NULL;
|
|
}
|
|
|
|
if (m_pDAOFields != NULL)
|
|
{
|
|
m_pDAOFields->Release();
|
|
m_pDAOFields = NULL;
|
|
}
|
|
|
|
if (m_pDAOTableDef != NULL)
|
|
{
|
|
m_pDAOTableDef->Release();
|
|
m_pDAOTableDef = NULL;
|
|
}
|
|
|
|
m_bOpen = FALSE;
|
|
m_bNew = FALSE;
|
|
|
|
// Remove the tabledef from the CDaoDatabase's map
|
|
m_pDatabase->m_mapTableDefs.RemoveKey(this);
|
|
}
|
|
|
|
BOOL CDaoTableDef::CanUpdate()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
short nUpdatable;
|
|
DAO_CHECK(m_pDAOTableDef->get_Updatable(&nUpdatable));
|
|
return nUpdatable == AFX_DAO_TRUE;
|
|
}
|
|
|
|
void CDaoTableDef::SetName(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOTableDef->put_Name(V_BSTR(&var)));
|
|
}
|
|
|
|
CString CDaoTableDef::GetName()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOTableDef->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoTableDef::SetSourceTableName(LPCTSTR lpszSrcTableName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var(lpszSrcTableName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOTableDef->put_SourceTableName(
|
|
V_BSTR(&var)));
|
|
}
|
|
|
|
CString CDaoTableDef::GetSourceTableName()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOTableDef->get_SourceTableName(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoTableDef::SetConnect(LPCTSTR lpszConnect)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var(lpszConnect, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOTableDef->put_Connect(V_BSTR(&var)));
|
|
}
|
|
|
|
CString CDaoTableDef::GetConnect()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOTableDef->get_Connect(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoTableDef::SetAttributes(long lAttributes)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
DAO_CHECK(m_pDAOTableDef->put_Attributes(lAttributes));
|
|
}
|
|
|
|
long CDaoTableDef::GetAttributes()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
long lAttributes;
|
|
DAO_CHECK(m_pDAOTableDef->get_Attributes(&lAttributes));
|
|
return lAttributes;
|
|
}
|
|
|
|
COleDateTime CDaoTableDef::GetDateCreated()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant varDate;
|
|
DAO_CHECK(m_pDAOTableDef->get_DateCreated(&varDate));
|
|
return varDate.date;
|
|
}
|
|
|
|
COleDateTime CDaoTableDef::GetDateLastUpdated()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant varDate;
|
|
DAO_CHECK(m_pDAOTableDef->get_LastUpdated(&varDate));
|
|
return varDate.date;
|
|
}
|
|
|
|
void CDaoTableDef::SetValidationRule(
|
|
LPCTSTR lpszValidationRule)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var(lpszValidationRule, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOTableDef->put_ValidationRule(
|
|
V_BSTR(&var)));
|
|
}
|
|
|
|
CString CDaoTableDef::GetValidationRule()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOTableDef->get_ValidationRule(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoTableDef::SetValidationText(
|
|
LPCTSTR lpszValidationText)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var(lpszValidationText, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOTableDef->put_ValidationText(
|
|
V_BSTR(&var)));
|
|
}
|
|
|
|
CString CDaoTableDef::GetValidationText()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOTableDef->get_ValidationText(
|
|
&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
long CDaoTableDef::GetRecordCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
long lRecordCount;
|
|
DAO_CHECK(m_pDAOTableDef->get_RecordCount(&lRecordCount));
|
|
return lRecordCount;
|
|
}
|
|
|
|
void CDaoTableDef::CreateField(LPCTSTR lpszName, short nType, long lSize,
|
|
long lAttributes)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CDaoFieldInfo fieldinfo;
|
|
|
|
// Initialize everything so only correct properties will be set
|
|
fieldinfo.m_strName = lpszName;
|
|
fieldinfo.m_nType = nType;
|
|
fieldinfo.m_lSize = lSize;
|
|
fieldinfo.m_lAttributes = lAttributes;
|
|
fieldinfo.m_nOrdinalPosition = 0;
|
|
fieldinfo.m_bRequired = FALSE;
|
|
fieldinfo.m_bAllowZeroLength = FALSE;
|
|
fieldinfo.m_lCollatingOrder = 0;
|
|
|
|
CreateField(fieldinfo);
|
|
}
|
|
|
|
void CDaoTableDef::CreateField(CDaoFieldInfo& fieldinfo)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAOField* pDAOField;
|
|
|
|
// Create the DAO field object (setting basic properties)
|
|
DAO_CHECK(m_pDAOTableDef->CreateField(
|
|
COleVariant(fieldinfo.m_strName, VT_BSTRT),
|
|
COleVariant(fieldinfo.m_nType),
|
|
COleVariant(fieldinfo.m_lSize), &pDAOField));
|
|
|
|
TRY
|
|
{
|
|
// Basic properties already set, so set the rest
|
|
AfxSetFieldInfo(pDAOField, fieldinfo);
|
|
|
|
// Append the field object to the fields collection
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
DAO_CHECK(m_pDAOFields->Append(pDAOField));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
pDAOField->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOField->Release();
|
|
}
|
|
|
|
void CDaoTableDef::DeleteField(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
ASSERT(lpszName != NULL);
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOFields->Delete(V_BSTR(&var)));
|
|
}
|
|
|
|
void CDaoTableDef::DeleteField(int nIndex)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CDaoFieldInfo fieldinfo;
|
|
GetFieldInfo(nIndex, fieldinfo, AFX_DAO_PRIMARY_INFO);
|
|
DeleteField((LPCTSTR)fieldinfo.m_strName);
|
|
}
|
|
|
|
void CDaoTableDef::CreateIndex(CDaoIndexInfo& indexinfo)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAOIndex* pDAOIndex;
|
|
|
|
DAO_CHECK(m_pDAOTableDef->CreateIndex(
|
|
COleVariant(indexinfo.m_strName, VT_BSTRT), &pDAOIndex));
|
|
|
|
TRY
|
|
{
|
|
// Set the index info
|
|
AfxSetIndexInfo(pDAOIndex, indexinfo);
|
|
|
|
// Append the field object to the fields collection
|
|
if (m_pDAOIndexes == NULL)
|
|
InitIndexesCollection();
|
|
DAO_CHECK(m_pDAOIndexes->Append(pDAOIndex));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
pDAOIndex->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOIndex->Release();
|
|
}
|
|
|
|
void CDaoTableDef::DeleteIndex(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(lpszName != NULL);
|
|
|
|
if (m_pDAOIndexes == NULL)
|
|
InitIndexesCollection();
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOIndexes->Delete(V_BSTR(&var)));
|
|
}
|
|
|
|
void CDaoTableDef::DeleteIndex(int nIndex)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CDaoIndexInfo indexinfo;
|
|
GetIndexInfo(nIndex, indexinfo, AFX_DAO_PRIMARY_INFO);
|
|
DeleteIndex((LPCTSTR)indexinfo.m_strName);
|
|
}
|
|
|
|
short CDaoTableDef::GetFieldCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nFields;
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
DAO_CHECK(m_pDAOFields->get_Count(&nFields));
|
|
return nFields;
|
|
}
|
|
|
|
void CDaoTableDef::GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOField* pDAOField;
|
|
DAO_CHECK(m_pDAOFields->get_Item(
|
|
COleVariant((long)nIndex), &pDAOField));
|
|
AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOField->Release();
|
|
}
|
|
|
|
void CDaoTableDef::GetFieldInfo(LPCTSTR lpszName,
|
|
CDaoFieldInfo& fieldinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOField* pDAOField;
|
|
DAO_CHECK(m_pDAOFields->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOField));
|
|
AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOField->Release();
|
|
}
|
|
|
|
short CDaoTableDef::GetIndexCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nIndexes;
|
|
|
|
if (m_pDAOIndexes == NULL)
|
|
InitIndexesCollection();
|
|
|
|
DAO_CHECK(m_pDAOIndexes->get_Count(&nIndexes));
|
|
return nIndexes;
|
|
}
|
|
|
|
void CDaoTableDef::GetIndexInfo(int nIndex, CDaoIndexInfo& indexinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOIndexes == NULL)
|
|
InitIndexesCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOIndex* pDAOIndex;
|
|
DAO_CHECK(m_pDAOIndexes->get_Item(
|
|
COleVariant((long)nIndex), &pDAOIndex));
|
|
AfxGetIndexInfo(pDAOIndex, indexinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOIndex->Release();
|
|
}
|
|
|
|
void CDaoTableDef::GetIndexInfo(LPCTSTR lpszName,
|
|
CDaoIndexInfo& indexinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOIndexes == NULL)
|
|
InitIndexesCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOIndex* pDAOIndex;
|
|
DAO_CHECK(m_pDAOIndexes->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOIndex));
|
|
AfxGetIndexInfo(pDAOIndex, indexinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOIndex->Release();
|
|
}
|
|
|
|
void CDaoTableDef::RefreshLink()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOTableDef != NULL);
|
|
|
|
DAO_CHECK(m_pDAOTableDef->RefreshLink());
|
|
}
|
|
|
|
//Implementation functions
|
|
void CDaoTableDef::InitFieldsCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAO_CHECK(m_pDAOTableDef->get_Fields(&m_pDAOFields));
|
|
}
|
|
|
|
void CDaoTableDef::InitIndexesCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAO_CHECK(m_pDAOTableDef->get_Indexes(&m_pDAOIndexes));
|
|
}
|
|
|
|
void CDaoTableDef::ThrowDaoException(int nAfxDaoError)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AfxThrowDaoException(nAfxDaoError);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoTableDef::AssertValid() const
|
|
{
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
void CDaoTableDef::Dump(CDumpContext& dc) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CObject::Dump(dc);
|
|
|
|
dc << "m_bOpen = " << m_bOpen;
|
|
dc << "\nm_bNew = " << m_bNew;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CDaoQueryDef
|
|
IMPLEMENT_DYNAMIC(CDaoQueryDef, CObject)
|
|
|
|
CDaoQueryDef::CDaoQueryDef(CDaoDatabase* pDatabase)
|
|
{
|
|
m_bOpen = FALSE;
|
|
m_bNew = FALSE;
|
|
|
|
m_pDatabase = pDatabase;
|
|
m_pDAOQueryDef = NULL;
|
|
m_pDAOParameters = NULL;
|
|
m_pDAOFields = NULL;
|
|
}
|
|
|
|
CDaoQueryDef::~CDaoQueryDef()
|
|
{
|
|
if (IsOpen())
|
|
Close();
|
|
else if (m_bNew)
|
|
{
|
|
// Remove the querydef from the CDaoDatabase's map
|
|
m_pDatabase->m_mapQueryDefs.RemoveKey(this);
|
|
}
|
|
}
|
|
|
|
void CDaoQueryDef::Create(LPCTSTR lpszName, LPCTSTR lpszSQL)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(!IsOpen());
|
|
|
|
// Create a temp querydef if lpszName is NULL or empty string
|
|
if (lpszName == NULL || *lpszName == '\0')
|
|
{
|
|
DAO_CHECK(m_pDatabase->m_pDAODatabase->CreateQueryDef(
|
|
COleVariant(_T(""), VT_BSTRT),
|
|
COleVariant(lpszSQL, VT_BSTRT),
|
|
&m_pDAOQueryDef));
|
|
m_bOpen = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// Create a template querydef
|
|
// (preventing automatic append to QueryDefs collection)
|
|
DAO_CHECK(m_pDatabase->m_pDAODatabase->CreateQueryDef(
|
|
_afxOptionalVariant, _afxOptionalVariant, &m_pDAOQueryDef));
|
|
m_bNew = TRUE;
|
|
|
|
// Now set the name and SQL if necessary
|
|
SetName(lpszName);
|
|
if (lpszSQL != NULL)
|
|
SetSQL(lpszSQL);
|
|
}
|
|
|
|
// Add the querydef to map of Open/New CDaoQueryDefs
|
|
m_pDatabase->m_mapQueryDefs.SetAt(this, this);
|
|
}
|
|
|
|
void CDaoQueryDef::Append()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_bNew);
|
|
ASSERT(m_pDAOQueryDef != NULL);
|
|
|
|
DAOQueryDefs* pDAOQueryDefs;
|
|
DAO_CHECK(m_pDatabase->m_pDAODatabase->get_QueryDefs(
|
|
&pDAOQueryDefs));
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(pDAOQueryDefs->Append(m_pDAOQueryDef));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
pDAOQueryDefs->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOQueryDefs->Release();
|
|
|
|
m_bNew = FALSE;
|
|
m_bOpen = TRUE;
|
|
}
|
|
|
|
// Open a pre-defined query or create a temp query
|
|
void CDaoQueryDef::Open(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(!m_bNew);
|
|
|
|
// Re-open is not allowed
|
|
if (IsOpen())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
// Null lpszName implies create a temp query
|
|
if (lpszName == NULL)
|
|
{
|
|
DAO_CHECK(m_pDatabase->m_pDAODatabase->CreateQueryDef(
|
|
COleVariant(_T(""), VT_BSTRT), _afxOptionalVariant, &m_pDAOQueryDef));
|
|
}
|
|
else
|
|
{
|
|
COleVariant varName(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDatabase->m_pDAODatabase->OpenQueryDef(
|
|
V_BSTR(&varName), &m_pDAOQueryDef));
|
|
}
|
|
|
|
m_bOpen = TRUE;
|
|
|
|
// Add the querydef to map of Open/New CDaoQueryDefs
|
|
m_pDatabase->m_mapQueryDefs.SetAt(this, this);
|
|
}
|
|
|
|
void CDaoQueryDef::Close()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOParameters != NULL)
|
|
{
|
|
m_pDAOParameters->Release();
|
|
m_pDAOParameters = NULL;
|
|
}
|
|
|
|
if (m_pDAOFields != NULL)
|
|
{
|
|
m_pDAOFields->Release();
|
|
m_pDAOFields = NULL;
|
|
}
|
|
|
|
if (m_pDAOQueryDef != NULL)
|
|
{
|
|
// DAO Close is a no op, but call it anyway
|
|
DAO_TRACE(m_pDAOQueryDef->Close());
|
|
m_pDAOQueryDef->Release();
|
|
m_pDAOQueryDef = NULL;
|
|
}
|
|
|
|
m_bOpen = FALSE;
|
|
m_bNew = FALSE;
|
|
|
|
// Remove the querydef from the CDaoDatabase's map
|
|
m_pDatabase->m_mapQueryDefs.RemoveKey(this);
|
|
}
|
|
|
|
BOOL CDaoQueryDef::CanUpdate()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nUpdatable;
|
|
DAO_CHECK(m_pDAOQueryDef->get_Updatable(&nUpdatable));
|
|
return nUpdatable == AFX_DAO_TRUE;
|
|
}
|
|
|
|
CString CDaoQueryDef::GetName()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOQueryDef->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoQueryDef::SetName(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOQueryDef->put_Name(V_BSTR(&var)));
|
|
}
|
|
|
|
CString CDaoQueryDef::GetSQL()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOQueryDef->get_SQL(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoQueryDef::SetSQL(LPCTSTR lpszSQL)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
|
|
COleVariant var(lpszSQL, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOQueryDef->put_SQL(V_BSTR(&var)));
|
|
}
|
|
|
|
short CDaoQueryDef::GetType()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nType;
|
|
DAO_CHECK(m_pDAOQueryDef->get_Type(&nType));
|
|
return nType;
|
|
}
|
|
|
|
COleDateTime CDaoQueryDef::GetDateCreated()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
COleVariant varDate;
|
|
DAO_CHECK(m_pDAOQueryDef->get_DateCreated(&varDate));
|
|
return varDate.date;
|
|
}
|
|
|
|
COleDateTime CDaoQueryDef::GetDateLastUpdated()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
COleVariant varDate;
|
|
DAO_CHECK(m_pDAOQueryDef->get_LastUpdated(&varDate));
|
|
return varDate.date;
|
|
}
|
|
|
|
CString CDaoQueryDef::GetConnect()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAOQueryDef->get_Connect(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoQueryDef::SetConnect(LPCTSTR lpszConnect)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
|
|
COleVariant var(lpszConnect, VT_BSTRT);
|
|
DAO_CHECK(m_pDAOQueryDef->put_Connect(V_BSTR(&var)));
|
|
}
|
|
|
|
short CDaoQueryDef::GetODBCTimeout()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nTimeout;
|
|
DAO_CHECK(m_pDAOQueryDef->get_ODBCTimeout(&nTimeout));
|
|
return nTimeout;
|
|
}
|
|
|
|
void CDaoQueryDef::SetODBCTimeout(short nODBCTimeout)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
|
|
DAO_CHECK(m_pDAOQueryDef->put_ODBCTimeout(nODBCTimeout));
|
|
}
|
|
|
|
BOOL CDaoQueryDef::GetReturnsRecords()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nReturnsRecords;
|
|
DAO_CHECK(m_pDAOQueryDef->get_ReturnsRecords(&nReturnsRecords));
|
|
return nReturnsRecords == AFX_DAO_TRUE;
|
|
}
|
|
|
|
void CDaoQueryDef::SetReturnsRecords(BOOL bReturnsRecords)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
|
|
DAO_CHECK(m_pDAOQueryDef->put_ReturnsRecords(
|
|
(short)(bReturnsRecords ? AFX_DAO_TRUE : AFX_DAO_FALSE)));
|
|
}
|
|
|
|
long CDaoQueryDef::GetRecordsAffected()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
long lRecordsAffected;
|
|
DAO_CHECK(m_pDAOQueryDef->get_RecordsAffected(&lRecordsAffected));
|
|
return lRecordsAffected;
|
|
}
|
|
|
|
void CDaoQueryDef::Execute(int nOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pDAOQueryDef != NULL);
|
|
|
|
DAO_CHECK(m_pDAOQueryDef->Execute(COleVariant((long)nOptions)));
|
|
}
|
|
|
|
COleVariant CDaoQueryDef::GetParamValue(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOQueryDef != NULL);
|
|
|
|
if (m_pDAOParameters == NULL)
|
|
InitParametersCollection();
|
|
|
|
DAOParameter* pDAOParameter = NULL;
|
|
COleVariant var;
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(m_pDAOParameters->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOParameter));
|
|
DAO_CHECK(pDAOParameter->get_Value(&var));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pDAOParameter != NULL)
|
|
pDAOParameter->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOParameter->Release();
|
|
return var;
|
|
}
|
|
|
|
COleVariant CDaoQueryDef::GetParamValue(int nIndex)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAOQueryDef != NULL);
|
|
|
|
if (m_pDAOParameters == NULL)
|
|
InitParametersCollection();
|
|
|
|
DAOParameter* pDAOParameter = NULL;
|
|
COleVariant var;
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(m_pDAOParameters->get_Item(
|
|
COleVariant((long)nIndex), &pDAOParameter));
|
|
DAO_CHECK(pDAOParameter->get_Value(&var));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pDAOParameter != NULL)
|
|
pDAOParameter->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOParameter->Release();
|
|
return var;
|
|
}
|
|
|
|
void CDaoQueryDef::SetParamValue(LPCTSTR lpszName,
|
|
const COleVariant& varValue)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
ASSERT(m_pDAOQueryDef != NULL);
|
|
|
|
if (m_pDAOParameters == NULL)
|
|
InitParametersCollection();
|
|
|
|
DAOParameter* pDAOParameter = NULL;
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(m_pDAOParameters->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOParameter));
|
|
DAO_CHECK(pDAOParameter->put_Value(varValue));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pDAOParameter != NULL)
|
|
pDAOParameter->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOParameter->Release();
|
|
}
|
|
|
|
void CDaoQueryDef::SetParamValue(int nIndex,
|
|
const COleVariant& varValue)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen() || m_bNew);
|
|
ASSERT(m_pDAOQueryDef != NULL);
|
|
|
|
if (m_pDAOParameters == NULL)
|
|
InitParametersCollection();
|
|
|
|
DAOParameter* pDAOParameter = NULL;
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(m_pDAOParameters->get_Item(
|
|
COleVariant((long)nIndex), &pDAOParameter));
|
|
DAO_CHECK(pDAOParameter->put_Value(varValue));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pDAOParameter != NULL)
|
|
pDAOParameter->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pDAOParameter->Release();
|
|
}
|
|
|
|
void CDaoQueryDef::SetParamValueNull(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
SetParamValue(lpszName, _afxNullVariant);
|
|
}
|
|
|
|
void CDaoQueryDef::SetParamValueNull(int nIndex)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
SetParamValue(nIndex, _afxNullVariant);
|
|
}
|
|
|
|
short CDaoQueryDef::GetFieldCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nFields;
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
DAO_CHECK(m_pDAOFields->get_Count(&nFields));
|
|
return nFields;
|
|
}
|
|
|
|
void CDaoQueryDef::GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOField* pDAOField;
|
|
DAO_CHECK(m_pDAOFields->get_Item(
|
|
COleVariant((long)nIndex), &pDAOField));
|
|
AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOField->Release();
|
|
}
|
|
|
|
void CDaoQueryDef::GetFieldInfo(LPCTSTR lpszName,
|
|
CDaoFieldInfo& fieldinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOField* pDAOField;
|
|
DAO_CHECK(m_pDAOFields->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOField));
|
|
AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOField->Release();
|
|
}
|
|
|
|
short CDaoQueryDef::GetParameterCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nParameters;
|
|
|
|
if (m_pDAOParameters == NULL)
|
|
InitParametersCollection();
|
|
|
|
DAO_CHECK(m_pDAOParameters->get_Count(&nParameters));
|
|
return nParameters;
|
|
}
|
|
|
|
void CDaoQueryDef::GetParameterInfo(int nIndex,
|
|
CDaoParameterInfo& paraminfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOParameters == NULL)
|
|
InitParametersCollection();
|
|
|
|
// Get DAOParameter object and fill in parameter info struct
|
|
DAOParameter* pDAOParameter;
|
|
DAO_CHECK(m_pDAOParameters->get_Item(
|
|
COleVariant((long)nIndex), &pDAOParameter));
|
|
FillParameterInfo(pDAOParameter, paraminfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOParameter->Release();
|
|
}
|
|
|
|
void CDaoQueryDef::GetParameterInfo(LPCTSTR lpszName,
|
|
CDaoParameterInfo& paraminfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOParameters == NULL)
|
|
InitParametersCollection();
|
|
|
|
// Get DAOParameter object and fill in parameter info struct
|
|
DAOParameter* pDAOParameter;
|
|
DAO_CHECK(m_pDAOParameters->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOParameter));
|
|
FillParameterInfo(pDAOParameter, paraminfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOParameter->Release();
|
|
}
|
|
|
|
//Implementation functions
|
|
void CDaoQueryDef::InitFieldsCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAO_CHECK(m_pDAOQueryDef->get_Fields(&m_pDAOFields));
|
|
}
|
|
|
|
void CDaoQueryDef::InitParametersCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
DAO_CHECK(m_pDAOQueryDef->get_Parameters(&m_pDAOParameters));
|
|
}
|
|
|
|
void CDaoQueryDef::FillParameterInfo(DAOParameter* pDAOParameter,
|
|
CDaoParameterInfo& paraminfo, DWORD dwOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(pDAOParameter != NULL);
|
|
ASSERT(dwOptions != NULL);
|
|
|
|
COleVariant var;
|
|
|
|
if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
|
|
{
|
|
// All parameter info is basic info
|
|
DAO_CHECK(pDAOParameter->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
paraminfo.m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOParameter->get_Type(
|
|
¶minfo.m_nType));
|
|
|
|
DAO_CHECK(pDAOParameter->get_Value(
|
|
¶minfo.m_varValue));
|
|
}
|
|
}
|
|
|
|
void CDaoQueryDef::ThrowDaoException(int nAfxDaoError)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AfxThrowDaoException(nAfxDaoError);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoQueryDef::AssertValid() const
|
|
{
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
void CDaoQueryDef::Dump(CDumpContext& dc) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CObject::Dump(dc);
|
|
|
|
dc << "m_bOpen = " << m_bOpen;
|
|
dc << "\nm_bNew = " << m_bNew;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CDaoRecordset
|
|
IMPLEMENT_DYNAMIC(CDaoRecordset, CObject )
|
|
|
|
CDaoRecordset::CDaoRecordset(CDaoDatabase* pDatabase)
|
|
{
|
|
m_bOpen = FALSE;
|
|
|
|
m_pMapFieldCache = NULL;
|
|
m_pMapFieldIndex = NULL;
|
|
m_bCheckCacheForDirtyFields = TRUE;
|
|
|
|
m_prgDaoColBindInfo = NULL;
|
|
m_pulColumnLengths = NULL;
|
|
m_pbFieldFlags = NULL;
|
|
m_pbParamFlags = NULL;
|
|
|
|
m_pDAORecordset = NULL;
|
|
m_pICDAORecordsetGetRows = NULL;
|
|
m_pQueryDef = NULL;
|
|
m_pTableDef = NULL;
|
|
m_pDAOFields = NULL;
|
|
m_pDAOIndexes = NULL;
|
|
|
|
m_pDatabase = pDatabase;
|
|
|
|
m_nDefaultType = dbOpenDynaset;
|
|
m_nStatus = 0;
|
|
m_nFields = 0;
|
|
m_nParams = 0;
|
|
}
|
|
|
|
CDaoRecordset::~CDaoRecordset()
|
|
{
|
|
if (IsOpen())
|
|
Close();
|
|
|
|
// Clean up database if necessary
|
|
if (m_pDatabase != NULL && (m_nStatus & AFX_DAO_IMPLICIT_DB))
|
|
{
|
|
m_pDatabase->Close();
|
|
delete m_pDatabase;
|
|
m_pDatabase = NULL;
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::Open(int nOpenType, LPCTSTR lpszSQL, int nOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(nOpenType == AFX_DAO_USE_DEFAULT_TYPE ||
|
|
nOpenType == dbOpenDynaset || nOpenType == dbOpenSnapshot ||
|
|
dbOpenTable);
|
|
|
|
// Re-Opening is invalid.
|
|
if (IsOpen())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
if (nOpenType == AFX_DAO_USE_DEFAULT_TYPE)
|
|
m_nOpenType = m_nDefaultType;
|
|
else
|
|
m_nOpenType = nOpenType;
|
|
|
|
// Snapshots readOnly in DAO model.
|
|
if (m_nOpenType == dbOpenSnapshot)
|
|
nOptions |= dbReadOnly;
|
|
|
|
// Cache parameters and initialize
|
|
m_nOptions = nOptions;
|
|
m_cbFixedLengthFields = 0;
|
|
|
|
// Cache information for use in Requery
|
|
m_strRequerySQL = lpszSQL;
|
|
m_strRequeryFilter = m_strFilter;
|
|
m_strRequerySort = m_strSort;
|
|
|
|
AllocDatabase();
|
|
|
|
m_strSQL = lpszSQL;
|
|
if (m_strSQL.IsEmpty())
|
|
m_strSQL = GetDefaultSQL();
|
|
|
|
// Open table directly if option specified
|
|
if (m_nOpenType == dbOpenTable)
|
|
{
|
|
m_pTableDef = new CDaoTableDef(m_pDatabase);
|
|
m_nStatus |= AFX_DAO_IMPLICIT_TD;
|
|
|
|
TRY
|
|
{
|
|
// Must remove the bracket from the name
|
|
StripBrackets(m_strSQL, m_strSQL.GetBuffer(0));
|
|
m_strSQL.ReleaseBuffer();
|
|
|
|
m_pTableDef->Open(m_strSQL);
|
|
|
|
// Open the DAO recordset (implicit MoveFirst)
|
|
DAO_CHECK(m_pTableDef->m_pDAOTableDef->OpenRecordset(
|
|
COleVariant((long)m_nOpenType), COleVariant((long)m_nOptions),
|
|
&m_pDAORecordset));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Once recordset marked as open, Close handles this
|
|
if (m_pTableDef->IsOpen())
|
|
m_pTableDef->Close();
|
|
delete m_pTableDef;
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
else
|
|
{
|
|
m_pQueryDef = new CDaoQueryDef(m_pDatabase);
|
|
m_nStatus |= AFX_DAO_IMPLICIT_QD;
|
|
|
|
TRY
|
|
{
|
|
// If initial clause includes potential start of row returning
|
|
// query, then SQL passed to Open must be valid
|
|
// (Note: TABLE is valid for UNION-type queries)
|
|
if ((_tcsnicmp(m_strSQL, szSelect, _countof(szSelect)-1) != 0) &&
|
|
(_tcsnicmp(m_strSQL, szParameters, _countof(szParameters)-1) != 0) &&
|
|
(_tcsnicmp(m_strSQL, szTransform, _countof(szTransform)-1) != 0) &&
|
|
(_tcsnicmp(m_strSQL, szTable, _countof(szTable)-1) != 0))
|
|
{
|
|
BuildSQL();
|
|
}
|
|
else
|
|
{
|
|
// Add the filter and sort
|
|
if (!m_strFilter.IsEmpty())
|
|
m_strSQL += szWhere + m_strFilter;
|
|
|
|
if (!m_strSort.IsEmpty())
|
|
m_strSQL += szOrderBy + m_strSort;
|
|
}
|
|
|
|
// Create and define temp query
|
|
m_pQueryDef->Open();
|
|
m_pQueryDef->SetSQL(m_strSQL);
|
|
|
|
BindParameters();
|
|
// Open the DAO recordset (implicit MoveFirst)
|
|
DAO_CHECK(m_pQueryDef->m_pDAOQueryDef->OpenRecordset(
|
|
COleVariant((long)m_nOpenType), COleVariant((long)m_nOptions),
|
|
&m_pDAORecordset));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Once recordset marked as open, Close handles this
|
|
if (m_pQueryDef->IsOpen())
|
|
m_pQueryDef->Close();
|
|
delete m_pQueryDef;
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
|
|
m_bOpen = TRUE;
|
|
|
|
// Add the recordset to map of Open CDaoRecordsets
|
|
m_pDatabase->m_mapRecordsets.SetAt(this, this);
|
|
|
|
TRY
|
|
{
|
|
BindFields();
|
|
GetDataAndFixupNulls();
|
|
SetCursorAttributes();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
Close();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
|
|
void CDaoRecordset::Open(CDaoQueryDef* pQueryDef, int nOpenType,
|
|
int nOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
// Must pass valid, open QueryDef
|
|
ASSERT(pQueryDef != NULL);
|
|
if (!pQueryDef->IsOpen())
|
|
ThrowDaoException(AFX_DAO_ERROR_OBJECT_NOT_OPEN);
|
|
|
|
// Re-Opening is invalid.
|
|
if (IsOpen())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
if (nOpenType == AFX_DAO_USE_DEFAULT_TYPE)
|
|
m_nOpenType = m_nDefaultType;
|
|
else
|
|
m_nOpenType = nOpenType;
|
|
|
|
// Can't open table type recordsets with QueryDef
|
|
ASSERT(m_nOpenType == dbOpenDynaset || m_nOpenType == dbOpenSnapshot);
|
|
|
|
// Snapshots readOnly in DAO model.
|
|
if (m_nOpenType == dbOpenSnapshot)
|
|
nOptions |= dbReadOnly;
|
|
|
|
// Cache parameters and initialize
|
|
m_nOptions = nOptions;
|
|
m_cbFixedLengthFields = 0;
|
|
|
|
// Use pre-defined query
|
|
m_pQueryDef = pQueryDef;
|
|
|
|
// Share the same database object
|
|
m_pDatabase = m_pQueryDef->m_pDatabase;
|
|
|
|
BindParameters();
|
|
|
|
// Open the DAO recordset (implicit MoveFirst)
|
|
DAO_CHECK(m_pQueryDef->m_pDAOQueryDef->OpenRecordset(
|
|
COleVariant((long)m_nOpenType), COleVariant((long)m_nOptions),
|
|
&m_pDAORecordset));
|
|
|
|
m_bOpen = TRUE;
|
|
|
|
// Add the recordset to map of Open CDaoRecordsets
|
|
m_pDatabase->m_mapRecordsets.SetAt(this, this);
|
|
|
|
TRY
|
|
{
|
|
BindFields();
|
|
GetDataAndFixupNulls();
|
|
SetCursorAttributes();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
Close();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
|
|
void CDaoRecordset::Open(CDaoTableDef* pTableDef, int nOpenType,
|
|
int nOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
// Must pass valid, open TableDef
|
|
ASSERT(pTableDef != NULL);
|
|
if (!pTableDef->IsOpen())
|
|
ThrowDaoException(AFX_DAO_ERROR_OBJECT_NOT_OPEN);
|
|
m_pTableDef = pTableDef;
|
|
|
|
// Re-Opening is invalid.
|
|
if (IsOpen())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
if (nOpenType == AFX_DAO_USE_DEFAULT_TYPE)
|
|
m_nOpenType = m_nDefaultType;
|
|
else
|
|
m_nOpenType = nOpenType;
|
|
|
|
// Cache parameters and initialize
|
|
m_nOptions = nOptions;
|
|
m_cbFixedLengthFields = 0;
|
|
|
|
// Share the same database object
|
|
m_pDatabase = m_pTableDef->m_pDatabase;
|
|
|
|
// Open the DAO recordset (implicit MoveFirst)
|
|
DAO_CHECK(m_pTableDef->m_pDAOTableDef->OpenRecordset(
|
|
COleVariant((long)m_nOpenType), COleVariant((long)m_nOptions),
|
|
&m_pDAORecordset));
|
|
|
|
m_bOpen = TRUE;
|
|
|
|
// Add the recordset to map of Open CDaoRecordsets
|
|
m_pDatabase->m_mapRecordsets.SetAt(this, this);
|
|
|
|
TRY
|
|
{
|
|
BindFields();
|
|
GetDataAndFixupNulls();
|
|
SetCursorAttributes();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
Close();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
|
|
void CDaoRecordset::Close()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (IsOpen())
|
|
FreeCache();
|
|
|
|
// Clean up name strings in ColBindInfo struct
|
|
if (m_prgDaoColBindInfo != NULL)
|
|
{
|
|
for (int nIndex = 0; nIndex < m_nFields; nIndex++)
|
|
{
|
|
#ifndef _UNICODE
|
|
delete[] (LPTSTR)m_prgDaoColBindInfo[nIndex].columnID.lpstr;
|
|
m_prgDaoColBindInfo[nIndex].columnID.lpstr = NULL;
|
|
#else
|
|
delete[] (LPTSTR)m_prgDaoColBindInfo[nIndex].columnID.lpwstr;
|
|
m_prgDaoColBindInfo[nIndex].columnID.lpwstr = NULL;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
delete[] m_prgDaoColBindInfo;
|
|
m_prgDaoColBindInfo = NULL;
|
|
|
|
delete[] m_pulColumnLengths;
|
|
m_pulColumnLengths = NULL;
|
|
|
|
delete[] m_pbFieldFlags;
|
|
m_pbFieldFlags = NULL;
|
|
|
|
if (m_pMapFieldIndex != NULL)
|
|
{
|
|
delete m_pMapFieldIndex;
|
|
m_pMapFieldIndex = NULL;
|
|
}
|
|
|
|
if (m_pDAOIndexes != NULL)
|
|
{
|
|
m_pDAOIndexes->Release();
|
|
m_pDAOIndexes = NULL;
|
|
}
|
|
|
|
if (m_pDAOFields != NULL)
|
|
{
|
|
m_pDAOFields->Release();
|
|
m_pDAOFields = NULL;
|
|
}
|
|
|
|
if (m_pICDAORecordsetGetRows != NULL)
|
|
{
|
|
m_pICDAORecordsetGetRows->Release();
|
|
m_pICDAORecordsetGetRows = NULL;
|
|
}
|
|
|
|
if (m_pDAORecordset != NULL)
|
|
{
|
|
DAO_TRACE(m_pDAORecordset->Close());
|
|
m_pDAORecordset->Release();
|
|
m_pDAORecordset = NULL;
|
|
}
|
|
|
|
// Cleanup TableDef if not user supplied
|
|
if (m_pTableDef != NULL && m_nStatus & AFX_DAO_IMPLICIT_TD)
|
|
{
|
|
m_pTableDef->Close();
|
|
delete m_pTableDef;
|
|
m_pTableDef = NULL;
|
|
}
|
|
|
|
// Cleanup QueryDef if not user supplied
|
|
if (m_pQueryDef != NULL && m_nStatus & AFX_DAO_IMPLICIT_QD)
|
|
{
|
|
m_pQueryDef->Close();
|
|
delete m_pQueryDef;
|
|
m_pQueryDef = NULL;
|
|
}
|
|
|
|
m_nStatus &= ~AFX_DAO_IMPLICIT_QD;
|
|
m_nStatus &= ~AFX_DAO_IMPLICIT_TD;
|
|
m_pQueryDef = NULL;
|
|
m_pTableDef = NULL;
|
|
|
|
m_bOpen = FALSE;
|
|
|
|
// Remove the recordset from the CDaoDatabase's map
|
|
m_pDatabase->m_mapRecordsets.RemoveKey(this);
|
|
}
|
|
|
|
void CDaoRecordset::Requery()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(CanRestart());
|
|
|
|
// If filter or sort strings changed, must Close and Open
|
|
// This is only effective if m_strFilter/m_strSort used
|
|
if ((m_pQueryDef != NULL &&
|
|
(m_nStatus & AFX_DAO_IMPLICIT_QD)) &&
|
|
((m_strRequeryFilter != m_strFilter) ||
|
|
(m_strRequerySort != m_strSort)))
|
|
{
|
|
Close();
|
|
Open(m_nOpenType, m_strRequerySQL, m_nOptions);
|
|
}
|
|
else
|
|
{
|
|
// Rebind parameters in case values have changed
|
|
BindParameters();
|
|
|
|
if (m_pQueryDef != NULL)
|
|
{
|
|
COleVariant varDisp;
|
|
varDisp.pdispVal = m_pQueryDef->m_pDAOQueryDef;
|
|
varDisp.vt = VT_DISPATCH;
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(m_pDAORecordset->Requery(varDisp));
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Reset vt to prevent release of DAOQueryDef
|
|
varDisp.vt = VT_EMPTY;
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
// Reset vt to prevent release of DAOQueryDef
|
|
varDisp.vt = VT_EMPTY;
|
|
}
|
|
else
|
|
// Must be a table type recordset (this will fail!)
|
|
DAO_CHECK(m_pDAORecordset->Requery(_afxOptionalVariant));
|
|
|
|
GetDataAndFixupNulls();
|
|
}
|
|
}
|
|
|
|
CString CDaoRecordset::GetDefaultDBName()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Override and add UNC path to .MDB file
|
|
return _T("");
|
|
}
|
|
|
|
CString CDaoRecordset::GetDefaultSQL()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Override and add table name or entire SQL SELECT statement
|
|
return _T("");
|
|
}
|
|
|
|
void CDaoRecordset::DoFieldExchange(CDaoFieldExchange* /* pFX */)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Do nothing if dynamic binding, otherwise override and add DFX calls
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsBOF()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nBOF;
|
|
DAO_CHECK(m_pDAORecordset->get_BOF(&nBOF));
|
|
return nBOF == AFX_DAO_TRUE;
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsEOF()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nEOF;
|
|
DAO_CHECK(m_pDAORecordset->get_EOF(&nEOF));
|
|
return nEOF == AFX_DAO_TRUE;
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsDeleted() const
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
return m_bDeleted;
|
|
}
|
|
|
|
BOOL CDaoRecordset::CanScroll() const
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
return m_bScrollable;
|
|
}
|
|
|
|
BOOL CDaoRecordset::CanUpdate() const
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nUpdatable;
|
|
DAO_CHECK(m_pDAORecordset->get_Updatable(&nUpdatable));
|
|
return nUpdatable == AFX_DAO_TRUE;
|
|
}
|
|
|
|
BOOL CDaoRecordset::CanAppend() const
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
return m_bAppendable;
|
|
}
|
|
|
|
BOOL CDaoRecordset::CanRestart()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
short nRestartable;
|
|
DAO_CHECK(m_pDAORecordset->get_Restartable(&nRestartable));
|
|
return nRestartable == AFX_DAO_TRUE;
|
|
}
|
|
|
|
BOOL CDaoRecordset::CanTransact()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nTransactions;
|
|
DAO_CHECK(m_pDAORecordset->get_Transactions(&nTransactions));
|
|
return nTransactions == AFX_DAO_TRUE;
|
|
}
|
|
|
|
BOOL CDaoRecordset::CanBookmark()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nBookmarkable;
|
|
DAO_CHECK(m_pDAORecordset->get_Bookmarkable(&nBookmarkable));
|
|
return nBookmarkable == AFX_DAO_TRUE;
|
|
}
|
|
|
|
CString CDaoRecordset::GetName()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAORecordset->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
short CDaoRecordset::GetType()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
short nType;
|
|
DAO_CHECK(m_pDAORecordset->get_Type(&nType));
|
|
return nType;
|
|
}
|
|
|
|
short CDaoRecordset::GetEditMode()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
short nEditMode;
|
|
DAO_CHECK(m_pDAORecordset->get_EditMode(&nEditMode));
|
|
return nEditMode;
|
|
}
|
|
|
|
CString CDaoRecordset::GetSQL() const
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
return m_strSQL;
|
|
}
|
|
|
|
COleDateTime CDaoRecordset::GetDateCreated()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant varDate;
|
|
DAO_CHECK(m_pDAORecordset->get_DateCreated(&varDate));
|
|
return varDate.date;
|
|
}
|
|
|
|
COleDateTime CDaoRecordset::GetDateLastUpdated()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant varDate;
|
|
DAO_CHECK(m_pDAORecordset->get_LastUpdated(&varDate));
|
|
return varDate.date;
|
|
}
|
|
|
|
COleVariant CDaoRecordset::GetLastModifiedBookmark()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAORecordset->get_LastModified(&var.parray));
|
|
var.vt = VT_ARRAY | VT_UI1;
|
|
|
|
return var;
|
|
}
|
|
|
|
CString CDaoRecordset::GetValidationRule()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAORecordset->get_ValidationRule(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
CString CDaoRecordset::GetValidationText()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAORecordset->get_ValidationText(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
CString CDaoRecordset::GetCurrentIndex()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAORecordset->get_Index(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
return V_BSTRT(&var);
|
|
}
|
|
|
|
void CDaoRecordset::SetCurrentIndex(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var(lpszName, VT_BSTRT);
|
|
DAO_CHECK(m_pDAORecordset->put_Index(V_BSTR(&var)));
|
|
|
|
// Refetch the data
|
|
GetDataAndFixupNulls();
|
|
}
|
|
|
|
long CDaoRecordset::GetRecordCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
long lRecordCount;
|
|
DAO_CHECK(m_pDAORecordset->get_RecordCount(&lRecordCount));
|
|
return lRecordCount;
|
|
}
|
|
|
|
void CDaoRecordset::SetFieldDirty(void* pv, BOOL bDirty)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_nFields <= 0)
|
|
{
|
|
// Can't set fields dirty if no bound fields
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
int nIndex = 0, nIndexEnd;
|
|
|
|
if (pv == NULL)
|
|
nIndexEnd = m_nFields - 1;
|
|
else
|
|
{
|
|
nIndex = nIndexEnd = GetFieldIndex(pv);
|
|
ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
|
|
}
|
|
|
|
while (nIndex <= nIndexEnd)
|
|
{
|
|
if (bDirty)
|
|
SetDirtyFieldStatus(nIndex);
|
|
else
|
|
ClearDirtyFieldStatus(nIndex);
|
|
nIndex++;
|
|
}
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsFieldDirty(void* pv)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nEditMode = GetEditMode();
|
|
|
|
// Fields can't be dirty if not in edit/addnew mode or no fields bound
|
|
if (nEditMode == dbEditNone || m_nFields <= 0)
|
|
return FALSE;
|
|
|
|
// Check if cache field values have changed and mark as dirty
|
|
if (m_bCheckCacheForDirtyFields)
|
|
{
|
|
if (nEditMode == dbEditInProgress)
|
|
MarkForEdit();
|
|
else
|
|
MarkForAddNew();
|
|
}
|
|
|
|
int nIndex = 0, nIndexEnd;
|
|
|
|
if (pv == NULL)
|
|
nIndexEnd = m_nFields - 1;
|
|
else
|
|
{
|
|
// Get the field index to use status array
|
|
nIndex = nIndexEnd = GetFieldIndex(pv);
|
|
ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
|
|
}
|
|
|
|
BOOL bDirty = FALSE;
|
|
|
|
while (nIndex <= nIndexEnd && !bDirty)
|
|
bDirty = IsFieldStatusDirty(nIndex++);
|
|
|
|
return bDirty;
|
|
}
|
|
|
|
void CDaoRecordset::SetFieldNull(void* pv, BOOL bNull)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_nFields <= 0)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
if (bNull)
|
|
{
|
|
// Need field exchange to set value to PSEUDO NULL.
|
|
CDaoFieldExchange fx(CDaoFieldExchange::SetFieldNull, this, pv);
|
|
fx.m_nFieldFound = 0;
|
|
DoFieldExchange(&fx);
|
|
|
|
// If no field found, index will still be zero
|
|
ASSERT(fx.m_nFieldFound != 0);
|
|
}
|
|
else
|
|
{
|
|
// Set status array not NULL. Don't need field exchange mechanism.
|
|
int nIndex = 0, nIndexEnd;
|
|
|
|
if (pv == NULL)
|
|
nIndexEnd = m_nFields - 1;
|
|
else
|
|
{
|
|
nIndex = nIndexEnd = GetFieldIndex(pv);
|
|
ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
|
|
}
|
|
|
|
while (nIndex <= nIndexEnd)
|
|
{
|
|
ClearNullFieldStatus(nIndex);
|
|
nIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsFieldNull(void* pv)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_nFields <= 0)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
int nIndex = 0, nIndexEnd;
|
|
|
|
if (pv == NULL)
|
|
nIndexEnd = m_nFields - 1;
|
|
else
|
|
{
|
|
// Get the field index to use status array
|
|
nIndex = nIndexEnd = GetFieldIndex(pv);
|
|
ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
|
|
}
|
|
|
|
BOOL bNull = FALSE;
|
|
|
|
while (nIndex <= nIndexEnd && !bNull)
|
|
bNull = IsFieldStatusNull(nIndex++);
|
|
|
|
return bNull;
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsFieldNullable(void* pv)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_nFields <= 0)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
int nIndex = 0, nIndexEnd;
|
|
|
|
if (pv == NULL)
|
|
nIndexEnd = m_nFields - 1;
|
|
else
|
|
{
|
|
// Get the field index to use status array
|
|
nIndex = nIndexEnd = GetFieldIndex(pv);
|
|
ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
|
|
}
|
|
|
|
BOOL bNullable = FALSE;
|
|
|
|
while (nIndex <= nIndexEnd && !bNullable)
|
|
{
|
|
if (!IsFieldStatusNullableKnown(nIndex))
|
|
{
|
|
CDaoFieldInfo fieldinfo;
|
|
GetFieldInfo(nIndex, fieldinfo, AFX_DAO_SECONDARY_INFO);
|
|
bNullable = !fieldinfo.m_bRequired;
|
|
if (bNullable)
|
|
SetNullableFieldStatus(nIndex);
|
|
SetNullableKnownFieldStatus(nIndex);
|
|
}
|
|
else
|
|
bNullable = IsFieldStatusNullable(nIndex);
|
|
|
|
nIndex++;
|
|
}
|
|
|
|
return bNullable;
|
|
}
|
|
|
|
short CDaoRecordset::GetFieldCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nFields;
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
DAO_CHECK(m_pDAOFields->get_Count(&nFields));
|
|
return nFields;
|
|
}
|
|
|
|
void CDaoRecordset::GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOField* pDAOField;
|
|
DAO_CHECK(m_pDAOFields->get_Item(
|
|
COleVariant((long)nIndex), &pDAOField));
|
|
AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOField->Release();
|
|
}
|
|
|
|
void CDaoRecordset::GetFieldInfo(LPCTSTR lpszName,
|
|
CDaoFieldInfo& fieldinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOField* pDAOField;
|
|
DAO_CHECK(m_pDAOFields->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOField));
|
|
AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOField->Release();
|
|
}
|
|
|
|
short CDaoRecordset::GetIndexCount()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
short nIndexes;
|
|
|
|
if (m_pDAOIndexes == NULL)
|
|
InitIndexesCollection();
|
|
|
|
DAO_CHECK(m_pDAOIndexes->get_Count(&nIndexes));
|
|
return nIndexes;
|
|
}
|
|
|
|
void CDaoRecordset::GetIndexInfo(int nIndex, CDaoIndexInfo& indexinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOIndexes == NULL)
|
|
InitIndexesCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOIndex* pDAOIndex;
|
|
DAO_CHECK(m_pDAOIndexes->get_Item(
|
|
COleVariant((long)nIndex), &pDAOIndex));
|
|
AfxGetIndexInfo(pDAOIndex, indexinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOIndex->Release();
|
|
}
|
|
|
|
void CDaoRecordset::GetIndexInfo(LPCTSTR lpszName,
|
|
CDaoIndexInfo& indexinfo, DWORD dwInfoOptions)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOIndexes == NULL)
|
|
InitIndexesCollection();
|
|
|
|
// Get DAOField object and fill in field info struct
|
|
DAOIndex* pDAOIndex;
|
|
DAO_CHECK(m_pDAOIndexes->get_Item(
|
|
COleVariant(lpszName, VT_BSTRT), &pDAOIndex));
|
|
AfxGetIndexInfo(pDAOIndex, indexinfo, dwInfoOptions);
|
|
|
|
// Clean up
|
|
pDAOIndex->Release();
|
|
}
|
|
|
|
COleVariant CDaoRecordset::GetBookmark()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAORecordset->get_Bookmark(&var.parray));
|
|
var.vt = VT_ARRAY | VT_UI1;
|
|
|
|
return var;
|
|
}
|
|
|
|
void CDaoRecordset::SetBookmark(COleVariant varBookmark)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->put_Bookmark(&varBookmark.parray));
|
|
|
|
GetDataAndFixupNulls();
|
|
}
|
|
|
|
long CDaoRecordset::GetAbsolutePosition()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
long lPosition;
|
|
DAO_CHECK(m_pDAORecordset->get_AbsolutePosition(&lPosition));
|
|
return lPosition;
|
|
}
|
|
|
|
void CDaoRecordset::SetAbsolutePosition(long lPosition)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->put_AbsolutePosition(lPosition));
|
|
|
|
GetDataAndFixupNulls();
|
|
}
|
|
|
|
float CDaoRecordset::GetPercentPosition()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
float fPosition;
|
|
DAO_CHECK(m_pDAORecordset->get_PercentPosition(&fPosition));
|
|
return fPosition;
|
|
}
|
|
|
|
void CDaoRecordset::SetPercentPosition(float fPosition)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->put_PercentPosition(fPosition));
|
|
|
|
GetDataAndFixupNulls();
|
|
}
|
|
|
|
void CDaoRecordset::MoveNext()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
Move(AFX_DAO_NEXT);
|
|
}
|
|
|
|
void CDaoRecordset::MovePrev()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
Move(AFX_DAO_PREV);
|
|
}
|
|
|
|
void CDaoRecordset::MoveFirst()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
Move(AFX_DAO_FIRST);
|
|
}
|
|
|
|
void CDaoRecordset::MoveLast()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
Move(AFX_DAO_LAST);
|
|
}
|
|
|
|
void CDaoRecordset::Move(long lRows)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
switch(lRows)
|
|
{
|
|
case AFX_DAO_NEXT:
|
|
DAO_CHECK(m_pDAORecordset->MoveNext());
|
|
break;
|
|
|
|
case AFX_DAO_PREV:
|
|
DAO_CHECK(m_pDAORecordset->MovePrevious());
|
|
break;
|
|
|
|
case AFX_DAO_FIRST:
|
|
DAO_CHECK(m_pDAORecordset->MoveFirst());
|
|
break;
|
|
|
|
case AFX_DAO_LAST:
|
|
DAO_CHECK(m_pDAORecordset->MoveLast());
|
|
break;
|
|
|
|
// General case
|
|
default:
|
|
// Call Move without getting Bookmark (using unitialized variant).
|
|
DAO_CHECK(m_pDAORecordset->Move(lRows, COleVariant()));
|
|
|
|
}
|
|
|
|
GetDataAndFixupNulls();
|
|
}
|
|
|
|
BOOL CDaoRecordset::FindNext(LPCTSTR lpszFilter)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return Find(AFX_DAO_NEXT, lpszFilter);
|
|
}
|
|
|
|
BOOL CDaoRecordset::FindPrev(LPCTSTR lpszFilter)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return Find(AFX_DAO_PREV, lpszFilter);
|
|
}
|
|
|
|
BOOL CDaoRecordset::FindFirst(LPCTSTR lpszFilter)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return Find(AFX_DAO_FIRST, lpszFilter);
|
|
}
|
|
|
|
BOOL CDaoRecordset::FindLast(LPCTSTR lpszFilter)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return Find(AFX_DAO_LAST, lpszFilter);
|
|
}
|
|
|
|
BOOL CDaoRecordset::Find(long lType, LPCTSTR lpszFilter)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var(lpszFilter, VT_BSTRT);
|
|
|
|
switch(lType)
|
|
{
|
|
default:
|
|
// Invalid Find type!
|
|
ASSERT(FALSE);
|
|
|
|
// fall through to FindNext case
|
|
|
|
case AFX_DAO_NEXT:
|
|
DAO_CHECK(m_pDAORecordset->FindNext(V_BSTR(&var)));
|
|
break;
|
|
|
|
case AFX_DAO_PREV:
|
|
DAO_CHECK(m_pDAORecordset->FindPrevious(V_BSTR(&var)));
|
|
break;
|
|
|
|
case AFX_DAO_FIRST:
|
|
DAO_CHECK(m_pDAORecordset->FindFirst(V_BSTR(&var)));
|
|
break;
|
|
|
|
case AFX_DAO_LAST:
|
|
DAO_CHECK(m_pDAORecordset->FindLast(V_BSTR(&var)));
|
|
break;
|
|
}
|
|
|
|
BOOL bMatch = IsMatch();
|
|
if (bMatch)
|
|
GetDataAndFixupNulls();
|
|
|
|
return bMatch;
|
|
}
|
|
|
|
BOOL CDaoRecordset::Seek(LPCTSTR lpszComparison, COleVariant* pKey1,
|
|
COleVariant* pKey2, COleVariant* pKey3)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
ASSERT(m_nOpenType == dbOpenTable);
|
|
|
|
// Must have at least one key
|
|
ASSERT(pKey1 != NULL);
|
|
|
|
COleVariant varComparison(lpszComparison, VT_BSTRT);
|
|
|
|
DAO_CHECK(m_pDAORecordset->Seek(V_BSTR(&varComparison),
|
|
pKey1 != NULL ? (VARIANT)*pKey1 : _afxOptionalVariant,
|
|
pKey2 != NULL ? (VARIANT)*pKey2 : _afxOptionalVariant,
|
|
pKey3 != NULL ? (VARIANT)*pKey3 : _afxOptionalVariant,
|
|
_afxOptionalVariant, _afxOptionalVariant, _afxOptionalVariant,
|
|
_afxOptionalVariant, _afxOptionalVariant, _afxOptionalVariant,
|
|
_afxOptionalVariant, _afxOptionalVariant, _afxOptionalVariant,
|
|
_afxOptionalVariant));
|
|
|
|
BOOL bMatch = IsMatch();
|
|
if (bMatch)
|
|
GetDataAndFixupNulls();
|
|
|
|
return bMatch;
|
|
}
|
|
|
|
BOOL CDaoRecordset::Seek(LPCTSTR lpszComparison, COleVariant* pKeyArray,
|
|
WORD nKeys)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
ASSERT(m_nOpenType == dbOpenTable);
|
|
|
|
// Must have at least one key and no more than 13
|
|
ASSERT(nKeys > 0);
|
|
ASSERT(nKeys < 14);
|
|
|
|
COleVariant varComparison(lpszComparison, VT_BSTRT);
|
|
LPVARIANT pVarArray[13];
|
|
|
|
for (WORD nIndex = 0; nIndex < nKeys; nIndex++)
|
|
pVarArray[nIndex] = &pKeyArray[nIndex];
|
|
|
|
for (;nIndex < 13; nIndex++)
|
|
pVarArray[nIndex] = &_afxOptionalVariant;
|
|
|
|
DAO_CHECK(m_pDAORecordset->Seek(V_BSTR(&varComparison),
|
|
*pVarArray[0], *pVarArray[1], *pVarArray[2], *pVarArray[3],
|
|
*pVarArray[4], *pVarArray[5], *pVarArray[6], *pVarArray[7],
|
|
*pVarArray[8], *pVarArray[9], *pVarArray[10], *pVarArray[11],
|
|
*pVarArray[12]));
|
|
|
|
BOOL bMatch = IsMatch();
|
|
if (bMatch)
|
|
GetDataAndFixupNulls();
|
|
|
|
return bMatch;
|
|
}
|
|
|
|
void CDaoRecordset::CancelUpdate()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->CancelUpdate());
|
|
|
|
// Restore cache if necessary
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0)
|
|
LoadFields();
|
|
}
|
|
|
|
void CDaoRecordset::SetLockingMode(BOOL bPessimistic)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->put_LockEdits(
|
|
(short)(bPessimistic ? AFX_DAO_TRUE : AFX_DAO_FALSE)));
|
|
}
|
|
|
|
BOOL CDaoRecordset::GetLockingMode()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
short nLockEdits;
|
|
DAO_CHECK(m_pDAORecordset->get_LockEdits(&nLockEdits));
|
|
return nLockEdits == AFX_DAO_TRUE;
|
|
}
|
|
|
|
void CDaoRecordset::SetCacheStart(COleVariant varBookmark)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->put_CacheStart(&varBookmark.parray));
|
|
}
|
|
|
|
COleVariant CDaoRecordset::GetCacheStart()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
COleVariant var;
|
|
DAO_CHECK(m_pDAORecordset->get_CacheStart(&var.parray));
|
|
var.vt = VT_ARRAY | VT_UI1;
|
|
|
|
return var;
|
|
}
|
|
|
|
void CDaoRecordset::SetCacheSize(long lSize)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->put_CacheSize(lSize));
|
|
}
|
|
|
|
long CDaoRecordset::GetCacheSize()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
long lSize;
|
|
DAO_CHECK(m_pDAORecordset->get_CacheSize(&lSize));
|
|
return lSize;
|
|
}
|
|
|
|
void CDaoRecordset::FillCache(long* pSize, COleVariant* pBookmark)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->FillCache(
|
|
pSize != NULL ? (VARIANT)COleVariant(*pSize) : _afxOptionalVariant,
|
|
pBookmark != NULL ? (VARIANT)*pBookmark : _afxOptionalVariant));
|
|
}
|
|
|
|
void CDaoRecordset::AddNew()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0)
|
|
{
|
|
short nEditMode = GetEditMode();
|
|
if (nEditMode != dbEditAdd)
|
|
{
|
|
// Store fields if necessary (fields already stored if edit mode)
|
|
if (nEditMode != dbEditInProgress)
|
|
{
|
|
AllocCache();
|
|
StoreFields();
|
|
}
|
|
|
|
// Set all fields NULL and not dirty
|
|
SetFieldNull(NULL);
|
|
SetFieldDirty(NULL, FALSE);
|
|
}
|
|
}
|
|
|
|
DAO_CHECK(m_pDAORecordset->AddNew());
|
|
}
|
|
|
|
void CDaoRecordset::Edit()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0)
|
|
{
|
|
short nEditMode = GetEditMode();
|
|
if (nEditMode != dbEditInProgress)
|
|
{
|
|
if (nEditMode == dbEditNone)
|
|
{
|
|
// Save fields for restore/dirty checking later
|
|
AllocCache();
|
|
StoreFields();
|
|
SetFieldDirty(NULL, FALSE);
|
|
}
|
|
else
|
|
// Load in fields cached on AddNew call prior to Edit
|
|
LoadFields();
|
|
}
|
|
}
|
|
|
|
DAO_CHECK(m_pDAORecordset->Edit());
|
|
}
|
|
|
|
void CDaoRecordset::Update()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
int nMode;
|
|
|
|
// If caching, compare cache to current values and save state
|
|
if (m_nFields > 0)
|
|
{
|
|
if (m_bCheckCacheForDirtyFields)
|
|
{
|
|
IsFieldDirty(NULL);
|
|
nMode = GetEditMode();
|
|
}
|
|
|
|
// Set all field values of all fields marked dirty
|
|
SetDirtyFields();
|
|
}
|
|
|
|
DAO_CHECK(m_pDAORecordset->Update());
|
|
|
|
// Restore data if data cached and were in add mode
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0 &&
|
|
nMode == dbEditAdd)
|
|
{
|
|
LoadFields();
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::Delete()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
DAO_CHECK(m_pDAORecordset->Delete());
|
|
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0)
|
|
{
|
|
SetFieldNull(NULL);
|
|
SetFieldDirty(NULL, FALSE);
|
|
}
|
|
|
|
m_bDeleted = TRUE;
|
|
}
|
|
|
|
COleVariant CDaoRecordset::GetFieldValue(LPCTSTR lpszName)
|
|
{
|
|
COleVariant var;
|
|
GetFieldValue(lpszName, var);
|
|
return var;
|
|
}
|
|
|
|
COleVariant CDaoRecordset::GetFieldValue(int nIndex)
|
|
{
|
|
COleVariant var;
|
|
GetFieldValue(nIndex, var);
|
|
return var;
|
|
}
|
|
|
|
void CDaoRecordset::GetFieldValue(LPCTSTR lpszName, COleVariant& varValue)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
// Clear out variant
|
|
varValue.Clear();
|
|
|
|
// Use DAO optimization. get_Collect will get the field object from
|
|
// the fields collection and fetch the value
|
|
DAO_CHECK(m_pDAORecordset->get_Collect(
|
|
COleVariant(lpszName, VT_BSTRT), &varValue));
|
|
}
|
|
|
|
void CDaoRecordset::GetFieldValue(int nIndex, COleVariant& varValue)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
// Clear out variant
|
|
varValue.Clear();
|
|
|
|
// Use DAO optimization. get_Collect will get the field object from
|
|
// the fields collection and fetch the value
|
|
DAO_CHECK(m_pDAORecordset->get_Collect(
|
|
COleVariant((long)nIndex), &varValue));
|
|
}
|
|
|
|
void CDaoRecordset::SetFieldValue(LPCTSTR lpszName,
|
|
const COleVariant& varValue)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
// Use DAO optimization. get_Collect will get the field object from
|
|
// the fields collection and fetch the value
|
|
DAO_CHECK(m_pDAORecordset->put_Collect(
|
|
COleVariant(lpszName, VT_BSTRT), varValue));
|
|
}
|
|
|
|
void CDaoRecordset::SetFieldValue(int nIndex,
|
|
const COleVariant& varValue)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pDAORecordset != NULL);
|
|
|
|
// Use DAO optimization. put_Collect will get the field object from
|
|
// the fields collection and write the value
|
|
DAO_CHECK(m_pDAORecordset->put_Collect(
|
|
COleVariant((long)nIndex), varValue));
|
|
}
|
|
|
|
void CDaoRecordset::SetFieldValue(int nIndex,
|
|
LPCTSTR lpszValue)
|
|
{
|
|
COleVariant varValue(lpszValue, VT_BSTRT);
|
|
SetFieldValue(nIndex, varValue);
|
|
}
|
|
|
|
void CDaoRecordset::SetFieldValue(LPCTSTR lpszName,
|
|
LPCTSTR lpszValue)
|
|
{
|
|
COleVariant varValue(lpszValue, VT_BSTRT);
|
|
SetFieldValue(lpszName, varValue);
|
|
}
|
|
|
|
void CDaoRecordset::SetFieldValueNull(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
SetFieldValue(lpszName, _afxNullVariant);
|
|
}
|
|
|
|
void CDaoRecordset::SetFieldValueNull(int nIndex)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
SetFieldValue(nIndex, _afxNullVariant);
|
|
}
|
|
|
|
COleVariant CDaoRecordset::GetParamValue(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pQueryDef != NULL);
|
|
|
|
return m_pQueryDef->GetParamValue(lpszName);
|
|
}
|
|
|
|
COleVariant CDaoRecordset::GetParamValue(int nIndex)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pQueryDef != NULL);
|
|
|
|
return m_pQueryDef->GetParamValue(nIndex);
|
|
}
|
|
|
|
void CDaoRecordset::SetParamValue(LPCTSTR lpszName,
|
|
const COleVariant& varValue)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pQueryDef != NULL);
|
|
|
|
m_pQueryDef->SetParamValue(lpszName, varValue);
|
|
}
|
|
|
|
void CDaoRecordset::SetParamValue(int nIndex,
|
|
const COleVariant& varValue)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
ASSERT(m_pQueryDef != NULL);
|
|
|
|
m_pQueryDef->SetParamValue(nIndex, varValue);
|
|
}
|
|
|
|
void CDaoRecordset::SetParamValueNull(LPCTSTR lpszName)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
SetParamValue(lpszName, _afxNullVariant);
|
|
}
|
|
|
|
void CDaoRecordset::SetParamValueNull(int nIndex)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
SetParamValue(nIndex, _afxNullVariant);
|
|
}
|
|
|
|
//Implementation functions
|
|
DWORD CDaoRecordset::GetFieldLength(int nFieldIndex)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
return m_pulColumnLengths[nFieldIndex];
|
|
}
|
|
|
|
void CDaoRecordset::InitFieldsCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
DAO_CHECK(m_pDAORecordset->get_Fields(&m_pDAOFields));
|
|
}
|
|
|
|
void CDaoRecordset::InitIndexesCollection()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
DAO_CHECK(m_pTableDef->m_pDAOTableDef->get_Indexes(&m_pDAOIndexes));
|
|
}
|
|
|
|
// "PARAMETERS <parameter list>;"
|
|
// "SELECT <select list> FROM <table list>"
|
|
// " WHERE <m_strFilter> ORDER BY <m_strSort>"
|
|
void CDaoRecordset::BuildSQL()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Assumes m_strSQL represents table list
|
|
CString strTableName = m_strSQL;
|
|
m_strSQL.Empty();
|
|
|
|
if (m_nParams > 0)
|
|
BuildParameterList();
|
|
BuildSelectList();
|
|
m_strSQL += szFrom + strTableName;
|
|
|
|
if (!m_strFilter.IsEmpty())
|
|
{
|
|
m_strSQL += szWhere;
|
|
m_strSQL += m_strFilter;
|
|
}
|
|
|
|
if (!m_strSort.IsEmpty())
|
|
{
|
|
m_strSQL += szOrderBy;
|
|
m_strSQL += m_strSort;
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::AllocDatabase()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Allocate and maintain database if necessary
|
|
if (m_pDatabase == NULL)
|
|
{
|
|
m_pDatabase = new CDaoDatabase;
|
|
m_pDatabase->m_nStatus |= AFX_DAO_IMPLICIT_DB;
|
|
m_nStatus |= AFX_DAO_IMPLICIT_DB;
|
|
}
|
|
|
|
// Open Database if necessary
|
|
if (!m_pDatabase->IsOpen())
|
|
m_pDatabase->Open((LPCTSTR)GetDefaultDBName(), FALSE, FALSE, NULL);
|
|
}
|
|
|
|
void CDaoRecordset::BuildSelectList()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_nFields > 0);
|
|
|
|
m_strSQL += szSelect;
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::AddToSelectList, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
|
|
void CDaoRecordset::BuildParameterList()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_nParams > 0);
|
|
|
|
m_strSQL += szParameters;
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::AddToParameterList, this);
|
|
DoFieldExchange(&fx);
|
|
|
|
if (fx.m_nParam != 0)
|
|
m_strSQL += _T(";");
|
|
else
|
|
m_strSQL.Empty();
|
|
}
|
|
|
|
void CDaoRecordset::BindFields()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_nFields > 0)
|
|
{
|
|
// Setup the DAO binding struct
|
|
ASSERT(m_prgDaoColBindInfo == NULL);
|
|
m_prgDaoColBindInfo = new DAOCOLUMNBINDING[m_nFields];
|
|
memset(m_prgDaoColBindInfo, 0, sizeof(DAOCOLUMNBINDING) * m_nFields);
|
|
m_pulColumnLengths = new DWORD[m_nFields];
|
|
m_pbFieldFlags = new BYTE[m_nFields];
|
|
memset(m_pbFieldFlags, 0, m_nFields);
|
|
|
|
m_DaoFetchRows.cRowsRequested = 1;
|
|
m_DaoFetchRows.dwFlags = DAOROWFETCH_BINDABSOLUTE;
|
|
m_DaoFetchRows.pData = NULL;
|
|
|
|
// Allocate the index map
|
|
ASSERT(m_pMapFieldIndex == NULL);
|
|
m_pMapFieldIndex = new CMapPtrToPtr;
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::BindField, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::BindParameters()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_nParams > 0)
|
|
{
|
|
// Since Jet treats non-bindable names as implicit parameters
|
|
// this should catch some SQL syntax errors that would otherwise
|
|
// appear to be uninitialized parameters.
|
|
ASSERT(m_pQueryDef->GetParameterCount() == m_nParams);
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::BindParam, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::Fixup()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::Fixup, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
|
|
void CDaoRecordset::AllocCache()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Do nothing if caching disabled by master switch
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0 &&
|
|
m_pMapFieldCache == NULL)
|
|
{
|
|
m_pMapFieldCache = new CMapPtrToPtr;
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::AllocCache, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::StoreFields()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Do nothing if caching disabled by master switch
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0)
|
|
{
|
|
ASSERT(m_pMapFieldCache != NULL);
|
|
CDaoFieldExchange fx(CDaoFieldExchange::StoreField, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::LoadFields()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Do nothing if caching disabled by master switch
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0)
|
|
{
|
|
CDaoFieldExchange fx(CDaoFieldExchange::LoadField, this);
|
|
DoFieldExchange(&fx);
|
|
|
|
// Clear the dirty status flags
|
|
SetFieldDirty(NULL, FALSE);
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::FreeCache()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Do nothing if caching disabled by master switch
|
|
if (m_bCheckCacheForDirtyFields && m_nFields > 0 &&
|
|
m_pMapFieldCache != NULL)
|
|
{
|
|
// Free up dynamically allocated mem in cache
|
|
CDaoFieldExchange fx(CDaoFieldExchange::FreeCache, this);
|
|
|
|
// Delete any cached data
|
|
void* pvKey;
|
|
void* pvObject;
|
|
POSITION pos = m_pMapFieldCache->GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
m_pMapFieldCache->GetNextAssoc(pos, pvKey, pvObject);
|
|
fx.DeleteCacheValue((CDaoFieldCache*)pvObject,
|
|
((CDaoFieldCache*)pvObject)->m_nDataType);
|
|
}
|
|
m_pMapFieldCache->RemoveAll();
|
|
|
|
delete m_pMapFieldCache;
|
|
m_pMapFieldCache = NULL;
|
|
}
|
|
}
|
|
|
|
void CDaoRecordset::MarkForAddNew()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::MarkForAddNew, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
|
|
void CDaoRecordset::MarkForEdit()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::MarkForEdit, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
|
|
int CDaoRecordset::GetFieldIndex(void* pv)
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(m_pMapFieldIndex != NULL);
|
|
|
|
void* pvIndex;
|
|
|
|
if (!m_pMapFieldIndex->Lookup(pv, pvIndex))
|
|
return AFX_DAO_DATA_NOT_FOUND;
|
|
else
|
|
// Index was stored rather than ptr, make it 0-based
|
|
return ((int)pvIndex) - 1;
|
|
}
|
|
|
|
void CDaoRecordset::SetDirtyFields()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
if (m_pDAOFields == NULL)
|
|
InitFieldsCollection();
|
|
|
|
CDaoFieldExchange fx(CDaoFieldExchange::SetDirtyField, this);
|
|
DoFieldExchange(&fx);
|
|
}
|
|
|
|
void CDaoRecordset::SetCursorAttributes()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
m_bScrollable = !(m_nOptions & dbForwardOnly);
|
|
m_bAppendable = CanUpdate() ||
|
|
(!(m_nOptions & dbReadOnly) && (m_nOptions & dbAppendOnly));
|
|
}
|
|
|
|
void CDaoRecordset::GetDataAndFixupNulls()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
// Don't need to do anything if no fields bound
|
|
if (m_nFields > 0)
|
|
{
|
|
if (IsEOF() || IsBOF())
|
|
{
|
|
// If no current record, simple mark fields NULL
|
|
if (m_nFields > 0)
|
|
SetFieldNull(NULL);
|
|
}
|
|
else
|
|
{
|
|
if (m_pICDAORecordsetGetRows == NULL)
|
|
{
|
|
DAO_CHECK(m_pDAORecordset->QueryInterface(
|
|
IID_ICDAORecordset, (void**)&m_pICDAORecordsetGetRows));
|
|
}
|
|
|
|
// Call GetRows to fill in the bound data
|
|
SCODE scode = m_pICDAORecordsetGetRows->GetRows(
|
|
0, m_nFields, m_prgDaoColBindInfo,
|
|
m_cbFixedLengthFields, &m_DaoFetchRows);
|
|
|
|
// Check for GetRows specific errors
|
|
// This is necessary as ICDAORecordset::GetRows
|
|
// errors are not appended to DAO errors collection
|
|
if (FAILED(scode))
|
|
ThrowGetRowsDaoException(scode);
|
|
|
|
// Check to see if row deleted as it is just warning
|
|
m_bDeleted = scode == S_RECORDDELETED;
|
|
|
|
// Reset the status array
|
|
ClearFieldStatusFlags();
|
|
|
|
// Fixup Null fields
|
|
Fixup();
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsFieldStatusDirty(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return ((m_pbFieldFlags[nField] & AFX_DAO_FIELD_FLAG_DIRTY) ==
|
|
AFX_DAO_FIELD_FLAG_DIRTY);
|
|
}
|
|
|
|
void CDaoRecordset::SetDirtyFieldStatus(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
m_pbFieldFlags[nField] |= AFX_DAO_FIELD_FLAG_DIRTY;
|
|
}
|
|
|
|
void CDaoRecordset::ClearDirtyFieldStatus(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
m_pbFieldFlags[nField] &= ~AFX_DAO_FIELD_FLAG_DIRTY;
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsFieldStatusNull(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return ((m_pbFieldFlags[nField] & AFX_DAO_FIELD_FLAG_NULL) ==
|
|
AFX_DAO_FIELD_FLAG_NULL);
|
|
}
|
|
|
|
void CDaoRecordset::SetNullFieldStatus(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
m_pbFieldFlags[nField] |= AFX_DAO_FIELD_FLAG_NULL;
|
|
}
|
|
|
|
void CDaoRecordset::ClearNullFieldStatus(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
m_pbFieldFlags[nField] &= ~AFX_DAO_FIELD_FLAG_NULL;
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsFieldStatusNullable(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return ((m_pbFieldFlags[nField] & AFX_DAO_FIELD_FLAG_NULLABLE) ==
|
|
AFX_DAO_FIELD_FLAG_NULLABLE);
|
|
}
|
|
|
|
void CDaoRecordset::SetNullableFieldStatus(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
m_pbFieldFlags[nField] |= AFX_DAO_FIELD_FLAG_NULLABLE;
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsFieldStatusNullableKnown(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
return ((m_pbFieldFlags[nField] & AFX_DAO_FIELD_FLAG_NULLABLE_KNOWN)
|
|
== AFX_DAO_FIELD_FLAG_NULLABLE_KNOWN);
|
|
}
|
|
|
|
void CDaoRecordset::SetNullableKnownFieldStatus(UINT nField)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
m_pbFieldFlags[nField] |= AFX_DAO_FIELD_FLAG_NULLABLE_KNOWN;
|
|
}
|
|
|
|
void CDaoRecordset::ClearFieldStatusFlags()
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
memset(m_pbFieldFlags, 0, m_nFields);
|
|
}
|
|
|
|
BOOL CDaoRecordset::IsMatch()
|
|
{
|
|
ASSERT_VALID(this);
|
|
ASSERT(IsOpen());
|
|
|
|
short nNoMatch;
|
|
|
|
DAO_CHECK(m_pDAORecordset->get_NoMatch(&nNoMatch));
|
|
|
|
// Return TRUE if NoMatch is FALSE
|
|
return nNoMatch == AFX_DAO_FALSE;
|
|
}
|
|
|
|
void AFX_CDECL CDaoRecordset::StripBrackets(LPCTSTR lpszSrc, LPTSTR lpszDest)
|
|
{
|
|
while (*lpszSrc != '\0')
|
|
{
|
|
// Ignore all brackets
|
|
while (*lpszSrc == '[' || *lpszSrc == ']')
|
|
lpszSrc = _tcsinc(lpszSrc);
|
|
|
|
// Quit if at the end of the string
|
|
if (*lpszSrc == '\0')
|
|
break;
|
|
|
|
// Copy the data and increment the buffers
|
|
if (_istlead(*lpszSrc))
|
|
*lpszDest++ = *lpszSrc++;
|
|
*lpszDest++ = *lpszSrc++;
|
|
}
|
|
|
|
// Add the trailing '\0'
|
|
*lpszDest = '\0';
|
|
}
|
|
|
|
void CDaoRecordset::ThrowDaoException(int nAfxDaoError)
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
AfxThrowDaoException(nAfxDaoError);
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void CDaoRecordset::AssertValid() const
|
|
{
|
|
CObject::AssertValid();
|
|
}
|
|
|
|
void CDaoRecordset::Dump(CDumpContext& dc) const
|
|
{
|
|
ASSERT_VALID(this);
|
|
|
|
CObject::Dump(dc);
|
|
|
|
dc << "\nm_bOpen = " << m_bOpen;
|
|
dc << "\nm_bAppendable = " << m_bAppendable;
|
|
dc << "\nm_bScrollable = " << m_bScrollable;
|
|
dc << "\nm_bDeleted = " << m_bDeleted;
|
|
|
|
dc << "\nm_nOpenType = " << m_nOpenType;
|
|
dc << "\nm_nDefaultType = " << m_nDefaultType;
|
|
dc << "\nm_nOptions = " << m_nOptions;
|
|
|
|
dc << "\nm_strSQL = " << m_strSQL;
|
|
dc << "\nm_strFilter = " << m_strFilter;
|
|
dc << "\nm_strSort = " << m_strSort;
|
|
dc << "\nm_strRequerySQL = " << m_strRequerySQL;
|
|
dc << "\nm_strRequeryFilter = " << m_strRequeryFilter;
|
|
dc << "\nm_strRequerySort = " << m_strRequerySort;
|
|
|
|
dc << "\nm_nFields = " << m_nFields;
|
|
dc << "\nm_nParams = " << m_nParams;
|
|
|
|
dc << "\nm_bCheckCacheForDirtyFields = " << m_bCheckCacheForDirtyFields;
|
|
dc << "\nm_nStatus = " << m_nStatus;
|
|
|
|
dc << "\n";
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Helpers - implementation
|
|
void AFX_CDECL AfxGetFieldInfo(DAOField* pDAOField, CDaoFieldInfo& fieldinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT(pDAOField != NULL);
|
|
ASSERT(dwInfoOptions != 0);
|
|
|
|
COleVariant var;
|
|
short nBool;
|
|
|
|
// Always fetch the Primary properties
|
|
if (dwInfoOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOField->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
fieldinfo.m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOField->get_Type(&fieldinfo.m_nType));
|
|
|
|
DAO_CHECK(pDAOField->get_Size(&fieldinfo.m_lSize));
|
|
|
|
DAO_CHECK(pDAOField->get_Attributes(&fieldinfo.m_lAttributes));
|
|
}
|
|
|
|
if (dwInfoOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOField->get_OrdinalPosition(
|
|
&fieldinfo.m_nOrdinalPosition));
|
|
|
|
DAO_CHECK(pDAOField->get_Required(&nBool));
|
|
fieldinfo.m_bRequired = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOField->get_AllowZeroLength(&nBool));
|
|
fieldinfo.m_bAllowZeroLength = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOField->get_CollatingOrder(
|
|
&fieldinfo.m_lCollatingOrder));
|
|
|
|
DAO_CHECK(pDAOField->get_SourceField(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
fieldinfo.m_strSourceField = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOField->get_SourceTable(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
fieldinfo.m_strSourceTable = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
TRY
|
|
{
|
|
DAO_CHECK(pDAOField->get_ForeignName(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
fieldinfo.m_strForeignName = V_BSTRT(&var);
|
|
var.Clear();
|
|
}
|
|
AND_CATCH(CDaoException, e)
|
|
{
|
|
// If this property not appropriate, set foreign name empty
|
|
if (e->m_scode != E_DAO_IllegalOperation)
|
|
THROW_LAST();
|
|
else
|
|
{
|
|
fieldinfo.m_strForeignName.Empty();
|
|
e->Delete();
|
|
}
|
|
}
|
|
END_CATCH
|
|
}
|
|
|
|
if (dwInfoOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOField->get_DefaultValue(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
fieldinfo.m_strDefaultValue = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOField->get_ValidationRule(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
fieldinfo.m_strValidationRule = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
DAO_CHECK(pDAOField->get_ValidationText(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
fieldinfo.m_strValidationText = V_BSTRT(&var);
|
|
var.Clear();
|
|
}
|
|
}
|
|
|
|
void AFX_CDECL AfxSetFieldInfo(DAOField* pDAOField, CDaoFieldInfo& fieldinfo)
|
|
{
|
|
// Assumes name, type and size set on direct DAO CreateField call
|
|
ASSERT(pDAOField != NULL);
|
|
|
|
if (fieldinfo.m_lAttributes != 0)
|
|
DAO_CHECK(pDAOField->put_Attributes(fieldinfo.m_lAttributes));
|
|
|
|
if (fieldinfo.m_nOrdinalPosition != 0)
|
|
{
|
|
DAO_CHECK(pDAOField->put_OrdinalPosition(
|
|
fieldinfo.m_nOrdinalPosition));
|
|
}
|
|
|
|
if (fieldinfo.m_bRequired)
|
|
DAO_CHECK(pDAOField->put_Required(AFX_DAO_TRUE));
|
|
|
|
if (fieldinfo.m_bAllowZeroLength)
|
|
DAO_CHECK(pDAOField->put_AllowZeroLength(AFX_DAO_TRUE));
|
|
|
|
if (!fieldinfo.m_strForeignName.IsEmpty())
|
|
{
|
|
COleVariant var(fieldinfo.m_strForeignName, VT_BSTRT);
|
|
DAO_CHECK(pDAOField->put_ForeignName(V_BSTR(&var)));
|
|
}
|
|
|
|
if (!fieldinfo.m_strValidationRule.IsEmpty())
|
|
{
|
|
COleVariant var(fieldinfo.m_strValidationRule, VT_BSTRT);
|
|
DAO_CHECK(pDAOField->put_ValidationRule(V_BSTR(&var)));
|
|
}
|
|
|
|
if (!fieldinfo.m_strValidationText.IsEmpty())
|
|
{
|
|
COleVariant var(fieldinfo.m_strValidationText, VT_BSTRT);
|
|
DAO_CHECK(pDAOField->put_ValidationText(V_BSTR(&var)));
|
|
}
|
|
|
|
if (!fieldinfo.m_strDefaultValue.IsEmpty())
|
|
{
|
|
COleVariant var(fieldinfo.m_strDefaultValue, VT_BSTRT);
|
|
DAO_CHECK(pDAOField->put_DefaultValue(V_BSTR(&var)));
|
|
}
|
|
}
|
|
|
|
void AFX_CDECL AfxGetIndexInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo,
|
|
DWORD dwInfoOptions)
|
|
{
|
|
ASSERT(pDAOIndex != NULL);
|
|
ASSERT(dwInfoOptions != 0);
|
|
|
|
COleVariant var;
|
|
short nBool;
|
|
|
|
if (dwInfoOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOIndex->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
indexinfo.m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
AfxGetIndexFieldInfo(pDAOIndex, indexinfo);
|
|
}
|
|
|
|
if (dwInfoOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOIndex->get_Primary(&nBool));
|
|
indexinfo.m_bPrimary = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOIndex->get_Unique(&nBool));
|
|
indexinfo.m_bUnique = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOIndex->get_Clustered(&nBool));
|
|
indexinfo.m_bClustered = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOIndex->get_IgnoreNulls(&nBool));
|
|
indexinfo.m_bIgnoreNulls = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOIndex->get_Required(&nBool));
|
|
indexinfo.m_bRequired = nBool == AFX_DAO_TRUE;
|
|
|
|
DAO_CHECK(pDAOIndex->get_Foreign(&nBool));
|
|
indexinfo.m_bForeign = nBool == AFX_DAO_TRUE;
|
|
}
|
|
|
|
if (dwInfoOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
|
|
{
|
|
DAO_CHECK(pDAOIndex->get_DistinctCount(
|
|
&indexinfo.m_lDistinctCount));
|
|
}
|
|
}
|
|
|
|
void AFX_CDECL AfxSetIndexInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo)
|
|
{
|
|
// Assumes name,set on direct DAO CreateIndex call
|
|
ASSERT(pDAOIndex != NULL);
|
|
|
|
AfxSetIndexFieldInfo(pDAOIndex, indexinfo);
|
|
|
|
if (indexinfo.m_bPrimary)
|
|
DAO_CHECK(pDAOIndex->put_Primary(AFX_DAO_TRUE));
|
|
|
|
if (indexinfo.m_bUnique)
|
|
DAO_CHECK(pDAOIndex->put_Unique(AFX_DAO_TRUE));
|
|
|
|
if (indexinfo.m_bClustered)
|
|
DAO_CHECK(pDAOIndex->put_Clustered(AFX_DAO_TRUE));
|
|
|
|
if (indexinfo.m_bIgnoreNulls)
|
|
DAO_CHECK(pDAOIndex->put_IgnoreNulls(AFX_DAO_TRUE));
|
|
|
|
if (indexinfo.m_bRequired)
|
|
DAO_CHECK(pDAOIndex->put_Required(AFX_DAO_TRUE));
|
|
}
|
|
|
|
void AFX_CDECL AfxGetIndexFields(DAOIndex* pDAOIndex,
|
|
DAOIndexFields** ppDAOIndexFields)
|
|
{
|
|
COleVariant var;
|
|
|
|
// Set the desired interface
|
|
GUID guidIndexFields;
|
|
#ifdef _UNICODE
|
|
guidIndexFields = IID_IDAOIndexFieldsW;
|
|
#else
|
|
guidIndexFields = IID_IDAOIndexFields;
|
|
#endif
|
|
|
|
// Get dispatch pointer to fields collection
|
|
DAO_CHECK(pDAOIndex->get_Fields(&var));
|
|
DAO_CHECK(var.pdispVal->QueryInterface(
|
|
guidIndexFields, (void**)ppDAOIndexFields));
|
|
}
|
|
|
|
void AFX_CDECL AfxGetIndexFieldInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo)
|
|
{
|
|
COleVariant var;
|
|
|
|
DAOIndexFields* pDAOIndexFields = NULL;
|
|
DAOField* pDAOField = NULL;
|
|
|
|
// Get the index fields collection
|
|
AfxGetIndexFields(pDAOIndex, &pDAOIndexFields);
|
|
|
|
TRY
|
|
{
|
|
// Get the number of fields in the index
|
|
short nCount;
|
|
DAO_CHECK(pDAOIndexFields->get_Count(&nCount));
|
|
|
|
// Allocate or reallocate memory for array if necessary
|
|
if (nCount != indexinfo.m_nFields)
|
|
{
|
|
if (indexinfo.m_nFields != 0)
|
|
{
|
|
// Check that allocation is correct.
|
|
ASSERT(indexinfo.m_nFields == 0 ||
|
|
indexinfo.m_bCleanupFieldInfo);
|
|
|
|
delete[] indexinfo.m_pFieldInfos;
|
|
indexinfo.m_pFieldInfos = NULL;
|
|
}
|
|
|
|
// Now allocate required memory
|
|
indexinfo.m_pFieldInfos = new CDaoIndexFieldInfo[nCount];
|
|
indexinfo.m_bCleanupFieldInfo = TRUE;
|
|
indexinfo.m_nFields = nCount;
|
|
}
|
|
|
|
// Now get field info for each field
|
|
long lAttributes;
|
|
for (short nIndex = 0; nIndex < indexinfo.m_nFields; nIndex++)
|
|
{
|
|
// Set the desired interface
|
|
GUID guidField;
|
|
#ifdef _UNICODE
|
|
guidField = IID_IDAOFieldW;
|
|
#else
|
|
guidField = IID_IDAOField;
|
|
#endif
|
|
|
|
// Get the field item
|
|
DAO_CHECK(pDAOIndexFields->get_Item(COleVariant(nIndex), &var));
|
|
DAO_CHECK(var.pdispVal->QueryInterface(
|
|
guidField, (void**)&pDAOField));
|
|
var.Clear();
|
|
|
|
// Get the field name
|
|
DAO_CHECK(pDAOField->get_Name(&V_BSTR(&var)));
|
|
var.vt = VT_BSTR;
|
|
indexinfo.m_pFieldInfos[nIndex].m_strName = V_BSTRT(&var);
|
|
var.Clear();
|
|
|
|
// Get the field attributes
|
|
DAO_CHECK(pDAOField->get_Attributes(&lAttributes));
|
|
indexinfo.m_pFieldInfos[nIndex].m_bDescending =
|
|
(lAttributes & dbDescending);
|
|
|
|
// Release and reset the field object
|
|
pDAOField->Release();
|
|
pDAOField = NULL;
|
|
}
|
|
|
|
// Release the index fields object
|
|
pDAOIndexFields->Release();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
// Release the field object if necessary
|
|
if (pDAOField != NULL)
|
|
pDAOField->Release();
|
|
|
|
// Must always release index fields collection
|
|
pDAOIndexFields->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
|
|
void AFX_CDECL AfxSetIndexFieldInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo)
|
|
{
|
|
COleVariant var;
|
|
long lAttributes;
|
|
|
|
DAOIndexFields* pDAOIndexFields = NULL;
|
|
DAOField* pDAOField = NULL;
|
|
|
|
// Get the index fields collection
|
|
AfxGetIndexFields(pDAOIndex, &pDAOIndexFields);
|
|
|
|
TRY
|
|
{
|
|
for (int nIndex = 0; nIndex < indexinfo.m_nFields; nIndex++)
|
|
{
|
|
// Create the field and set the name
|
|
DAO_CHECK(pDAOIndex->CreateField(
|
|
COleVariant(indexinfo.m_pFieldInfos[nIndex].m_strName, VT_BSTRT),
|
|
_afxOptionalVariant, _afxOptionalVariant, &pDAOField));
|
|
|
|
// Set the descending property
|
|
if (indexinfo.m_pFieldInfos[nIndex].m_bDescending)
|
|
lAttributes = dbDescending;
|
|
else
|
|
lAttributes = 0;
|
|
DAO_CHECK(pDAOField->put_Attributes(lAttributes));
|
|
|
|
// Append field to collection, release and reset
|
|
pDAOIndexFields->Append(pDAOField);
|
|
pDAOField->Release();
|
|
pDAOField = NULL;
|
|
}
|
|
|
|
// Always release the index fields object
|
|
pDAOIndexFields->Release();
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
if (pDAOField != NULL)
|
|
pDAOField->Release();
|
|
|
|
pDAOIndexFields->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// GetRows helper
|
|
void AFX_CDECL ThrowGetRowsDaoException(SCODE scode)
|
|
{
|
|
switch (scode)
|
|
{
|
|
case E_OUTOFMEMORY:
|
|
AfxThrowMemoryException();
|
|
|
|
default:
|
|
AfxThrowDaoException(NO_AFX_DAO_ERROR, scode);
|
|
|
|
// These are only (known) DAO 3.0 GetRows errors
|
|
case E_ROWTOOSHORT:
|
|
case E_BADBINDINFO:
|
|
case E_COLUMNUNAVAILABLE:
|
|
break;
|
|
}
|
|
|
|
CDaoException* pException;
|
|
pException = new CDaoException;
|
|
pException->m_pErrorInfo = new CDaoErrorInfo;
|
|
|
|
// Fill out the DAO error info struct
|
|
pException->m_scode = scode;
|
|
pException->m_pErrorInfo->m_strSource = _T("ICDAORecordset.GetRows");
|
|
pException->m_pErrorInfo->m_lErrorCode = LOWORD(scode);
|
|
|
|
// There is no help context or help file
|
|
pException->m_pErrorInfo->m_lHelpContext = 0;
|
|
|
|
int nID = 0;
|
|
|
|
if (scode == E_ROWTOOSHORT)
|
|
nID = AFX_IDP_DAO_ROWTOOSHORT;
|
|
else if (scode == E_BADBINDINFO)
|
|
nID = AFX_IDP_DAO_BADBINDINFO;
|
|
else
|
|
nID = AFX_IDP_DAO_COLUMNUNAVAILABLE;
|
|
|
|
VERIFY(pException->m_pErrorInfo->m_strDescription.LoadString(nID));
|
|
|
|
#ifdef _DEBUG
|
|
if (afxTraceFlags & traceDatabase)
|
|
{
|
|
TRACE1("\nError Code = %d\n",
|
|
pException->m_pErrorInfo->m_lErrorCode);
|
|
TRACE1("Source = %s\n",
|
|
(LPCTSTR)pException->m_pErrorInfo->m_strSource);
|
|
TRACE1("Description = %s\n",
|
|
(LPCTSTR)pException->m_pErrorInfo->m_strDescription);
|
|
}
|
|
#endif
|
|
|
|
THROW(pException);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// _AFX_DAO_STATE helper
|
|
_AFX_DAO_STATE* AFX_CDECL AfxGetDaoState()
|
|
{
|
|
// The DAO state is store in the module state
|
|
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
|
|
_AFX_DAO_STATE* pDaoState = pModuleState->m_pDaoState;
|
|
|
|
// Allocate a new DAO state if necessary
|
|
if (pDaoState == NULL)
|
|
{
|
|
pDaoState = new _AFX_DAO_STATE;
|
|
pModuleState->m_pDaoState = pDaoState;
|
|
}
|
|
return pDaoState;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// DAODBEngine helpers
|
|
void AFXAPI AfxDaoInit()
|
|
{
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
|
|
// Attempt to initialize OLE component objects
|
|
// (use default IMalloc allocator)
|
|
DAO_CHECK_ERROR(::CoInitialize(NULL),
|
|
AFX_DAO_ERROR_ENGINE_INITIALIZATION);
|
|
pDaoState->m_bOleInitialized = TRUE;
|
|
|
|
// Hook AfxDaoTerm to CWinApp, otherwise explicit AfxDaoTerm call req'd
|
|
CWinApp* pApp = AfxGetApp();
|
|
if (pApp != NULL)
|
|
pApp->m_lpfnDaoTerm = AfxDaoTerm;
|
|
|
|
// Set the interface type
|
|
GUID guidEngine;
|
|
#ifdef _UNICODE
|
|
guidEngine = IID_IDAODBEngineW;
|
|
#else
|
|
guidEngine = IID_IDAODBEngine;
|
|
#endif
|
|
|
|
LPCLASSFACTORY2 pCF2;
|
|
DAO_CHECK_ERROR(::CoGetClassObject(CLSID_CDAODBEngine,
|
|
CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory2, (LPVOID*)&pCF2),
|
|
AFX_DAO_ERROR_ENGINE_INITIALIZATION);
|
|
|
|
TRY
|
|
{
|
|
// DAO runtime key
|
|
COleVariant varKey(_T("mjgcqcejfchcijecpdhckcdjqigdejfccjri"));
|
|
|
|
DAO_CHECK_ERROR(pCF2->CreateInstanceLic( NULL, NULL, guidEngine,
|
|
V_BSTR(&varKey), (LPVOID*)&pDaoState->m_pDAODBEngine),
|
|
AFX_DAO_ERROR_ENGINE_INITIALIZATION);
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
pCF2->Release();
|
|
THROW_LAST();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
pCF2->Release();
|
|
}
|
|
|
|
DAODBEngine* AFXAPI AfxDaoGetEngine()
|
|
{
|
|
// Return DAODBEngine object for direct access
|
|
return AfxGetDaoState()->m_pDAODBEngine;
|
|
}
|
|
|
|
void AFXAPI AfxDaoTerm()
|
|
{
|
|
_AFX_DAO_STATE* pDaoState = AfxGetDaoState();
|
|
|
|
// Close any CDaoWorkspaces left around
|
|
void* pvKey;
|
|
void* pvObject;
|
|
POSITION pos = pDaoState->m_mapWorkspaces.GetStartPosition();
|
|
while (pos != NULL)
|
|
{
|
|
pDaoState->m_mapWorkspaces.GetNextAssoc(pos, pvKey, pvObject);
|
|
((CDaoWorkspace*)pvObject)->Close();
|
|
}
|
|
pDaoState->m_mapWorkspaces.RemoveAll();
|
|
|
|
// Clean up engine object if necessary
|
|
if (pDaoState->m_pDAODBEngine != NULL)
|
|
{
|
|
pDaoState->m_pDAODBEngine->Release();
|
|
pDaoState->m_pDAODBEngine = NULL;
|
|
}
|
|
|
|
// Shutdown OLE component objects if necessary
|
|
if (pDaoState->m_bOleInitialized)
|
|
{
|
|
::CoUninitialize();
|
|
pDaoState->m_bOleInitialized = FALSE;
|
|
}
|
|
|
|
// If hooked up to CWinApp, make sure to unhook
|
|
CWinApp* pApp = AfxGetApp();
|
|
if (pApp != NULL)
|
|
pApp->m_lpfnDaoTerm = NULL;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Inline function declarations expanded out-of-line
|
|
|
|
#ifndef _AFX_ENABLE_INLINES
|
|
|
|
static char _szAfxDaoInl[] = "afxdao.inl";
|
|
#undef THIS_FILE
|
|
#define THIS_FILE _szAfxDaoInl
|
|
#define _AFXDAOCORE_INLINE
|
|
#include "afxdao.inl"
|
|
|
|
#endif
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
#pragma warning(disable: 4074)
|
|
#pragma init_seg(lib)
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|