📄 arsdb.cpp
字号:
//---------------------------------------------------------------------
// arsdb.cpp - Copyright (C) 1998 by AIRES Group
// Implementation of AIRES Database Services
//---------------------------------------------------------------------
#include "stdafx.h"
#include "arsdb.h"
#include "comdef.h"
// Allow IsKindOf() macro
IMPLEMENT_DYNAMIC(CARSObject,CObject);
IMPLEMENT_DYNAMIC(CARSRecordset,CARSObject);
IMPLEMENT_DYNAMIC(CARSConnection,CARSObject);
IMPLEMENT_DYNAMIC(CARSException,CARSObject);
// Count of how many CARSConnection objects exist
DWORD CARSConnection::dwNumConnections = 0;
// CARSConnection::CARSConnection()
// Default Constructor
CARSConnection::CARSConnection():pConn(NULL)
{
if (!dwNumConnections++) {
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
AfxThrowARSException(ARSMSG_ERR_COM_INIT);
}
}
}
// CARSConnection::CARSConnection(connectStr, UID, PWD, flags)
// Constructor to open connection to database
CARSConnection::CARSConnection(LPCSTR pcsConnectStr, LPCSTR pcsUID, LPCSTR pcsPWD, long lFlags):pConn(NULL)
{
if (!dwNumConnections++) {
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
AfxThrowARSException(ARSMSG_ERR_COM_INIT);
}
}
Open(pcsConnectStr, pcsUID, pcsPWD, lFlags);
}
// CARSConnection::Open((connectStr, UID, PWD, flags)
// Open connection to database
void CARSConnection::Open(LPCSTR pcsConnectString, LPCSTR pcsUID, LPCSTR pcsPWD, long lFlags)
{
HRESULT hr;
_bstr_t bstrSource(pcsConnectString);
_bstr_t bstrUser(pcsUID);
_bstr_t bstrPassword(pcsPWD);
hr = CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_INPROC_SERVER, IID_IADOConnection, (LPVOID *)&pConn);
if (FAILED(hr)) {
AfxThrowARSException(ARSMSG_ERR_ADO_CON_INIT);
}
hr = pConn->Open( bstrSource, bstrUser, bstrPassword, lFlags);
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_CON_OPEN, ARSMSG_ERR_NO_ERROR, pConn);
}
// CARSConnection::~CARSConnection()
// Destructor closes connection.
CARSConnection::~CARSConnection()
{
Close();
}
// void CARSConnection::Close()
// Closes connection
void CARSConnection::Close()
{
if (pConn) {
pConn->Release();
pConn = NULL;
}
}
// BOOL CARSConnection::IsOpen()
// Returns true if connection is open
BOOL CARSConnection::IsOpen()
{
long state = adStateClosed;
BOOL ret = FALSE;
if (IsInitialized()) {
pConn->get_State(&state);
if (state == adStateOpen)
ret = TRUE;
}
return ret;
}
// BOOL CARSConnection::IsInitialized()
// Returns true if connection object is initialized
BOOL CARSConnection::IsInitialized()
{
return (pConn != NULL);
}
// void CARSConnection::BeginTrans(long *nestLevel)
// Begins new transaction returns nesting Level
void CARSConnection::BeginTrans(long *plNestingLevel)
{
if (plNestingLevel)
*plNestingLevel = -1;
if (IsInitialized())
pConn->BeginTrans(plNestingLevel);
}
// void CARSConnection::CommitTrans()
// Commit previously opened transaction
void CARSConnection::CommitTrans()
{
if (IsInitialized())
pConn->CommitTrans();
}
// void CARSConnection::RollbackTrans()
// Rollback previously opened transaction
void CARSConnection::RollbackTrans()
{
if (IsInitialized())
pConn->RollbackTrans();
}
// CARSRecordset *CARSConnection::OpenSchema(SchemaEnum Schema, VARIANT *Criteria, VARIANT *SchemaID)
// Opens schema for reading
// Allocates and returns new CARSRecordset object, it's responsobility of the caller to delete it
CARSRecordset *CARSConnection::OpenSchema(SchemaEnum Schema, VARIANT *Criteria, VARIANT *SchemaID)
{
ADORecordset *pSet = NULL;
if (IsInitialized()) {
pConn->OpenSchema(Schema, *Criteria, *SchemaID, &pSet);
if (pSet) return new CARSRecordset(pSet);
}
return NULL;
}
// CARSRecordset *Execute(LPCSTR pcsCommand, VARIANT *RecordsAffected = NULL, long lOptions = adCmdUnknown)
// Executes command and optionally returns number of records affected
CARSRecordset *CARSConnection::Execute(LPCSTR pcsCommand, VARIANT *RecordsAffected, long lOptions)
{
bstr_t bCommand(pcsCommand);
ADORecordset *pSet = NULL;
if (IsInitialized()) {
pConn->Execute(bCommand, RecordsAffected, lOptions, &pSet);
if (pSet)
return new CARSRecordset(pSet);
}
return NULL;
}
// Gets message from the resource DLL
CString arsmsg_GetMessage(UINT nID, BOOL *res)
{
char mbuff[ARSMSG_MAX_MSG_SIZE];
arsmsg_GetMessage(nID, mbuff, res);
return CString(mbuff);
}
// Throw ARS Exception
void AfxThrowARSException(UINT cause, UINT detailed, ADOConnection *pConn, UINT helpID)
{
throw new CARSException(cause, detailed, pConn, helpID);
}
// CARSRecordset::CARSRecordset(ADORecordset *_pSet)
// Private constructor used only by CARSConnection to initialize CARSRecordset with
// existing record set object
CARSRecordset::CARSRecordset(ADORecordset *_pSet):pSet(_pSet),pConnection(NULL)
{
VARIANT var;
HRESULT hr = pSet->get_ActiveConnection(&var);
if (!FAILED(hr)) {
if (var.vt == VT_DISPATCH)
pConnection = (ADOConnection *)var.pdispVal;
}
}
// CARSRecordset::CARSRecordset()
// Empty constructor, just initializes pSet to NULL
CARSRecordset::CARSRecordset():pSet(NULL),pConnection(NULL)
{
}
// CARSRecordset::CARSRecordset(LPCSTR pcsSource, CARSConnection *pConn, CursorTypeEnum cType, LockTypeEnum lType, long lOptions);
// Initializes recordset with either command or a table name in pcsSource and connection pConn.
CARSRecordset::CARSRecordset(LPCSTR pcsSource, CARSConnection *pConn, CursorTypeEnum cType, LockTypeEnum lType, long lOptions):pSet(NULL),pConnection(NULL)
{
Open(pcsSource, pConn, cType, lType, lOptions);
}
// CARSRecordset::CARSRecordset(CARSConnection *pConn, CursorTypeEnum cType, LockTypeEnum lType, long lOptions);
// Initializes recordset with either command or a table name in virtual GetSource() and connection pConn.
CARSRecordset::CARSRecordset(CARSConnection *pConn, CursorTypeEnum cType, LockTypeEnum lType, long lOptions):pSet(NULL),pConnection(NULL)
{
Open(pConn, cType, lType, lOptions);
}
// void CARSRecordset::Open(CARSConnection *pConn, CursorTypeEnum cType, LockTypeEnum lType, long lOptions);
// Initializes recordset with either command or a table name in virtual GetSource() and connection pConn.
void CARSRecordset::Open(CARSConnection *pConn, CursorTypeEnum cType, LockTypeEnum lType, long lOptions)
{
Open(GetSource(), pConn, cType, lType, lOptions);
}
// void CARSRecordset::Open(LPCSTR pcsSource, CARSConnection *pConn, CursorTypeEnum cType, LockTypeEnum lType, long lOptions);
// Opens recordset with either command or a table name in pcsSource and connection pConn.
void CARSRecordset::Open(LPCSTR pcsSource, CARSConnection *pConn, CursorTypeEnum cType, LockTypeEnum lType, long lOptions)
{
HRESULT hr;
if (!pConn || !pConn->pConn)
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
// Close existing connection first
if (IsInitialized())
Close();
else {
hr = CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_INPROC_SERVER, IID_IADORecordset, (LPVOID *)&pSet);
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_INIT);
}
BSTR bstrSQL = CString(pcsSource).AllocSysString();
if (bstrSQL == NULL)
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_INIT);
hr = pSet->put_Source(bstrSQL);
SysFreeString(bstrSQL);
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_INIT);
pConnection = pConn->pConn;
hr = pSet->putref_ActiveConnection(pConn->pConn);
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_INIT);
COleVariant vNull;
vNull.vt = VT_ERROR;
vNull.scode = DISP_E_PARAMNOTFOUND;
hr = pSet->Open(vNull, vNull, cType, lType, lOptions);
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_OPEN, ARSMSG_ERR_NO_ERROR, pConnection);
}
// CARSRecordset::~CARSRecordset()
// Destructor releases object
CARSRecordset::~CARSRecordset()
{
Close();
if (pSet) {
pSet->Release();
pSet = NULL;
}
}
// void CARSRecordset::Close()
// Releases closes connection and ADO object
void CARSRecordset::Close()
{
if (IsInitialized())
pSet->Close();
}
// BOOL CARSRecordset::IsOpen()
// Returns true if connection is open
BOOL CARSRecordset::IsOpen()
{
long state = adStateClosed;
BOOL ret = FALSE;
if (IsInitialized()) {
pSet->get_State(&state);
if (state == adStateOpen)
ret = TRUE;
}
return ret;
}
// BOOL CARSRecordset::IsInitialized()
// Returns true if connection object is initialized
BOOL CARSRecordset::IsInitialized()
{
return (pSet != NULL);
}
// BOOL CARSRecordset::IsBOF()
// Returns true if begining of file
BOOL CARSRecordset::IsBOF()
{
VARIANT_BOOL vbBool;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
pSet->get_BOF(&vbBool);
return vbBool != 0;
}
// BOOL CARSRecordset::IsEOF()
// Returns true if end of file
BOOL CARSRecordset::IsEOF()
{
VARIANT_BOOL vbBool;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
pSet->get_EOF(&vbBool);
return vbBool != 0;
}
// void CARSRecordset::MoveFirst()
// Move to the first record
void CARSRecordset::MoveFirst()
{
HRESULT hr;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
hr = pSet->MoveFirst();
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_CANTPOSITIONREC, ARSMSG_ERR_NO_ERROR, pConnection);
CopyDataFromDatabase();
}
// void CARSRecordset::MoveLast()
// Move to the last record
void CARSRecordset::MoveLast()
{
HRESULT hr;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
hr = pSet->MoveLast();
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_CANTPOSITIONREC, ARSMSG_ERR_NO_ERROR, pConnection);
CopyDataFromDatabase();
}
// void CARSRecordset::MoveNext()
// Move to the next record
void CARSRecordset::MoveNext()
{
HRESULT hr;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
hr = pSet->MoveNext();
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_CANTPOSITIONREC, ARSMSG_ERR_NO_ERROR, pConnection);
CopyDataFromDatabase();
}
// void CARSRecordset::MovePrevious()
// Move to the previous record
void CARSRecordset::MovePrevious()
{
HRESULT hr;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
hr = pSet->MovePrevious();
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_CANTPOSITIONREC, ARSMSG_ERR_NO_ERROR, pConnection);
CopyDataFromDatabase();
}
// void CARSRecordset::SetFilter(LPCSTR filter)
// Set find filter for MoveNext/Previous
void CARSRecordset::SetFilter(LPCSTR filter)
{
COleVariant v;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
v.SetString(filter, VT_BSTR);
pSet->put_Filter(v);
}
// virutal BOOL CARSRecordset::PositionToPK(long _pk_id)
// Set find filter for MoveNext/Previous
BOOL CARSRecordset::PositionToPK(long _pk_id)
{
CString flStr;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
flStr.Format("pk_id = %d", _pk_id);
SetFilter(flStr);
MoveFirst();
return !IsEOF();
}
// LPCSTR CARSRecordset::GetFilter()
// Returns filter which is currently in place
CString CARSRecordset::GetFilter()
{
COleVariant v;
CString sFilter;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
pSet->get_Filter(&v);
if (v.vt == VT_BSTR)
sFilter = v.bstrVal;
return sFilter;
}
// EditModeEnum CARSRecordset::GetEditMode()
// Returns current Recordset edit mode
EditModeEnum CARSRecordset::GetEditMode()
{
EditModeEnum eMode;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
pSet->get_EditMode(&eMode);
return eMode;
}
// void CARSRecordset::Delete(affectRecords)
// Deletes current record (if affectRecords = adAffectCurrent
// or delete all records matching Filter if adAffectGroup
void CARSRecordset::Delete(AffectEnum affectRecords)
{
HRESULT hr;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
hr = pSet->Delete(affectRecords);
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_CANTDELETE, ARSMSG_ERR_NO_ERROR, pConnection);
// CopyDataFromDatabase();
}
// void CARSRecordset::Update()
// Updates current record
void CARSRecordset::Update()
{
HRESULT hr;
VARIANT varFields, varValues;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
varFields.vt = VT_ERROR;
varFields.scode = DISP_E_PARAMNOTFOUND;
varValues.vt = VT_ERROR;
varValues.scode = DISP_E_PARAMNOTFOUND;
CopyDataToDatabase();
hr = pSet->Update(varFields, varValues);
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_CANTUPDATE, ARSMSG_ERR_NO_ERROR, pConnection);
CopyDataFromDatabase();
}
// void CARSRecordset::CancelUpdate()
// Cancels Updates to current record (only if called before Update())
void CARSRecordset::CancelUpdate()
{
HRESULT hr;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
hr = pSet->CancelUpdate();
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_CANTCANCELUPDATE, ARSMSG_ERR_NO_ERROR, pConnection);
CopyDataFromDatabase();
}
// void CARSRecordset::GetFieldValue(LPCSTR fieldName, VARIANT *value)
// Get Value of the field named fieldName
void CARSRecordset::GetFieldValue(LPCSTR fieldName, VARIANT *value)
{
HRESULT hr;
COleVariant varIndex;
ADOFields *pFields = NULL;
ADOField *pField = NULL;
if (!IsOpen())
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOTOPEN);
if (!value)
AfxThrowARSException(ARSMSG_ERR_GEN_INVALID_PARAMETER);
// We need a try block so that we can Release pField and pFields and then
// we can rethrow exception
try {
// Obtain pointer to fields collection
varIndex.SetString(fieldName, VT_BSTR);
hr = pSet->get_Fields(&pFields);
if (FAILED(hr))
AfxThrowARSException(ARSMSG_ERR_ADO_RECSET_NOFIELDS, ARSMSG_ERR_NO_ERROR, pConnection);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -