⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arsdb.cpp

📁 自己编写的一个数据库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------
// 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 + -