// EmpBiz.cpp : implementation file
//
#include "stdafx.h"
#include "Emp.h"
#include "EmpBiz.h"
#ifdef _DEBUG
//#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define THROW_ERR(exp)if (FAILED(hr = (exp))) throw hr
const LPCWSTR g_lpcwszSource = L"OLE_DB_NWind_Jet;";
const LPCWSTR g_lpcwszUser = L"Admin";
const LPCWSTR g_lpcwszPwd = L"";
const LPCWSTR g_lpcwszSQL = L"select EmployeeId, LastName, FirstName, Title, HomePhone from Employees";
/////////////////////////////////////////////////////////////////////////////
// CEmpBiz
CEmpBiz::CEmpBiz()
{
m_piConnection = NULL;
m_piEmpRecordSet = NULL;
m_fConnected = FALSE;
m_fRecordsetEmpty = TRUE;
}
CEmpBiz::~CEmpBiz()
{
if ( m_piConnection != NULL )
m_piConnection->Release();
if ( m_piEmpRecordSet != NULL )
m_piEmpRecordSet->Release();
m_varLastGoodRecord.Clear();
m_piConnection = NULL;
m_piEmpRecordSet = NULL;
}
long CEmpBiz::GetEmployeeId()
{
HRESULThr;
COleVariantvFldName, vID;
if (!m_fConnected)
return 0;
//Watch for empty recordset
if(m_fRecordsetEmpty)
return 0;
vFldName.bstrVal = CString(EMP_EMPLOYEE_ID).AllocSysString();
vFldName.vt = VT_BSTR;
THROW_ERR( m_piEmpRecordSet->get_Collect(vFldName, vID));
return VTOLONG(vID);
}
CString CEmpBiz::GetFirstName()
{
HRESULThr;
COleVariantvFldName, vFirstName;
if (!m_fConnected)
return "";
//Watch for empty recordset
if(m_fRecordsetEmpty)
return "";
vFldName.bstrVal = CString(EMP_FIRST_NAME).AllocSysString();
vFldName.vt = VT_BSTR;
THROW_ERR(m_piEmpRecordSet->get_Collect(vFldName, vFirstName) );
return VTOCSTR(vFirstName);
}
CString CEmpBiz::GetLastName()
{
HRESULThr;
COleVariantvFldName, vLastName;
if (!m_fConnected)
return "";
//Watch for empty recordset
if(m_fRecordsetEmpty)
return "";
vFldName.bstrVal = CString(EMP_LAST_NAME).AllocSysString();
vFldName.vt = VT_BSTR;
THROW_ERR(m_piEmpRecordSet->get_Collect(vFldName, vLastName) );
return VTOCSTR(vLastName);
}
CString CEmpBiz::GetHomePhone()
{
HRESULThr;
COleVariantvFldName, vHomePhone;
if (!m_fConnected)
return "";
//Watch for empty recordset
if(m_fRecordsetEmpty)
return "";
vFldName.bstrVal = CString(EMP_HOME_PHONE).AllocSysString();
vFldName.vt = VT_BSTR;
THROW_ERR(m_piEmpRecordSet->get_Collect(vFldName, vHomePhone) );
return VTOCSTR(vHomePhone);
}
CString CEmpBiz::GetTitle()
{
HRESULThr;
COleVariantvFldName, vTitle;
if (!m_fConnected)
return "";
//Watch for empty recordset
if(m_fRecordsetEmpty)
return "";
vFldName.bstrVal = CString(EMP_TITLE).AllocSysString();
vFldName.vt = VT_BSTR;
THROW_ERR(m_piEmpRecordSet->get_Collect(vFldName, vTitle) );
return VTOCSTR(vTitle);
}
BOOL CEmpBiz::IsAddMode()
{
HRESULThr;
EditModeEnumlEditMode;
THROW_ERR(m_piEmpRecordSet->get_EditMode(&lEditMode) );
return lEditMode == adEditAdd ;
}
void CEmpBiz::AddRecord()
{
// TODO: Add your control notification handler code here
HRESULThr;
VARIANTrgvFields;
VARIANTrgvValues;
if (!m_fConnected)
return;
ClearFilter() ;
//Watch for empty recordset
if(!m_fRecordsetEmpty && !IsAddMode() )
{
//Remember where we were before adding in case the user
//cancels and we have to return
THROW_ERR(m_piEmpRecordSet->get_Bookmark(m_varLastGoodRecord) );
}
rgvFields.vt = VT_ERROR;
rgvFields.scode = DISP_E_PARAMNOTFOUND;
rgvValues.vt = VT_ERROR;
rgvValues.scode = DISP_E_PARAMNOTFOUND;
THROW_ERR(m_piEmpRecordSet->AddNew(rgvFields, rgvValues) );
//THROW_ERR( m_piEmpRecordSet->Update(rgvFields, rgvValues) );
m_fRecordsetEmpty = FALSE;
return ;
}
void CEmpBiz::DeleteRecord()
{
// TODO: Add your control notification handler code here
HRESULThr;
EditModeEnumlEditMode;
VARIANT_BOOLvbEOF, vbBOF;
//Watch for empty recordset
if (!m_fConnected || m_fRecordsetEmpty)
return;
ClearFilter() ;
//Delete method depends on current mode
THROW_ERR(m_piEmpRecordSet->get_EditMode(&lEditMode) );
switch (lEditMode)
{
case adEditNone: // Just delete it
{
THROW_ERR( m_piEmpRecordSet->Delete(adAffectCurrent) );
THROW_ERR( m_piEmpRecordSet->MoveNext() );
//Watch for end of record set
THROW_ERR( m_piEmpRecordSet->get_EOF(&vbEOF) );
if(vbEOF)
{
THROW_ERR(m_piEmpRecordSet->MovePrevious() );
//Check for empty record set.
THROW_ERR( m_piEmpRecordSet->get_BOF(&vbBOF) );
if(vbBOF)
m_fRecordsetEmpty = TRUE;
}
break;
}
case adEditInProgress: //Forget changes
{
THROW_ERR( m_piEmpRecordSet->CancelUpdate() );
THROW_ERR( m_piEmpRecordSet->Delete(adAffectCurrent) );
THROW_ERR( m_piEmpRecordSet->MoveFirst() );
break;
}
case adEditAdd: //If new record, go back to last known
{
THROW_ERR( m_piEmpRecordSet->CancelUpdate() );
THROW_ERR( m_piEmpRecordSet->put_Bookmark(m_varLastGoodRecord) );
}
}
return ;
}
BOOL CEmpBiz::MoveNext()
{
// TODO: Add your control notification handler code here
HRESULThr;
VARIANT_BOOL vbEOF;
if (!m_fConnected || m_fRecordsetEmpty)
return FALSE;
ClearFilter() ;
THROW_ERR(m_piEmpRecordSet->MoveNext() );
//Watch for end of record set
THROW_ERR(m_piEmpRecordSet->get_EOF(&vbEOF) );
if(vbEOF)
{
THROW_ERR(m_piEmpRecordSet->MovePrevious() );
return FALSE;
}
else
{
return TRUE;
}
}
BOOL CEmpBiz::MovePrevious()
{
// TODO: Add your control notification handler code here
HRESULThr;
VARIANT_BOOL vbBOF;
if (!m_fConnected || m_fRecordsetEmpty)
return FALSE;
ClearFilter() ;
THROW_ERR(m_piEmpRecordSet->MovePrevious() );
//Watch for beginning of recordset
THROW_ERR(m_piEmpRecordSet->get_BOF(&vbBOF) );
if(vbBOF)
{
THROW_ERR(m_piEmpRecordSet->MoveNext() );
return FALSE;
}
else
{
return TRUE;
}
}
BOOL CEmpBiz::MoveFirst()
{
// TODO: Add your control notification handler code here
HRESULThr;
VARIANT_BOOL vbBOF;
if (!m_fConnected || m_fRecordsetEmpty)
return FALSE;
ClearFilter() ;
THROW_ERR(m_piEmpRecordSet->MoveFirst() );
//Watch for beginning of recordset
THROW_ERR(m_piEmpRecordSet->get_BOF(&vbBOF) );
if(vbBOF)
{
return FALSE;
}
else
{
return TRUE;
}
}
BOOL CEmpBiz::MoveLast()
{
// TODO: Add your control notification handler code here
HRESULThr;
VARIANT_BOOL vbEOF;
if (!m_fConnected || m_fRecordsetEmpty)
return FALSE;
ClearFilter() ;
THROW_ERR(m_piEmpRecordSet->MoveLast() );
//Watch for beginning of recordset
THROW_ERR(m_piEmpRecordSet->get_BOF(&vbEOF) );
if(vbEOF)
{
return FALSE;
}
else
{
return TRUE;
}
}
BOOL CEmpBiz::FindForward(CString strCriteria)
{
HRESULThr;
VARIANT_BOOLvbEOF;
COleVariantv;
if (!m_fConnected || m_fRecordsetEmpty)
return FALSE;
THROW_ERR(m_piEmpRecordSet->get_Filter(&v) );
if ( v.vt != VT_BSTR || strCriteria !=v.bstrVal )
{
v.vt = VT_BSTR;
v.bstrVal = strCriteria.AllocSysString();
THROW_ERR( m_piEmpRecordSet->put_Filter(v) );
}
else
{
THROW_ERR( m_piEmpRecordSet->MoveNext() );
}
//Watch for ending of recordset
THROW_ERR(m_piEmpRecordSet->get_EOF(&vbEOF));
if(vbEOF)
{
ClearFilter() ;
THROW_ERR( m_piEmpRecordSet->MoveLast() );
return FALSE;
}
else
{
return TRUE;
}
}
void CEmpBiz::ClearFilter()
{
HRESULThr;
VARIANTv;
if ( !m_fRecordsetEmpty)
{
v.vt = VT_I2;
v.iVal = adFilterNone;
THROW_ERR(m_piEmpRecordSet->put_Filter(v) );
}
}
//
//Update record in the database
//
void CEmpBiz::UpdateEmpRec(CString &strFirstName,
CString &strHomePhone, CString &strLastName,
CString &strTitle)
{
HRESULThr;
VARIANTvarFields;
VARIANTvarValues;
WCHAR*columnNames[4] = { L"firstName", L"Lastname", L"title", L"homePhone"};
ADOFields*pFields = NULL;
ADOField*pField = NULL;
CVarvarIndex(VT_BSTR);
COleVariantvarFieldVal;
if (m_fRecordsetEmpty)
return;
varFields.vt = VT_ERROR;
varFields.scode = DISP_E_PARAMNOTFOUND;
varValues.vt = VT_ERROR;
varValues.scode = DISP_E_PARAMNOTFOUND;
try
{
// get the fields interface
THROW_ERR( m_piEmpRecordSet->get_Fields(&pFields) );
varIndex = SysAllocString(columnNames[0]) ;
THROW_ERR( pFields->get_Item(varIndex, &pField) );
varFieldVal.vt = VT_BSTR;
varFieldVal.bstrVal = strFirstName.AllocSysString();
THROW_ERR( pField->put_Value(varFieldVal) );
varFieldVal.Clear();
varIndex = SysAllocString(columnNames[1]) ;
THROW_ERR( pFields->get_Item(varIndex, &pField) );
varFieldVal.vt = VT_BSTR;
varFieldVal.bstrVal = strLastName.AllocSysString();
THROW_ERR( pField->put_Value(varFieldVal) );
varFieldVal.Clear();
varIndex = SysAllocString(columnNames[2]) ;
THROW_ERR( pFields->get_Item(varIndex, &pField) );
varFieldVal.vt = VT_BSTR;
varFieldVal.bstrVal = strTitle.AllocSysString();
THROW_ERR( pField->put_Value(varFieldVal) );
varFieldVal.Clear();
varIndex = SysAllocString(columnNames[3]) ;
THROW_ERR( pFields->get_Item(varIndex, &pField) );
varFieldVal.vt = VT_BSTR;
varFieldVal.bstrVal = strHomePhone.AllocSysString();
THROW_ERR( pField->put_Value(varFieldVal) );
varFieldVal.Clear();
//Commit the changes
THROW_ERR( m_piEmpRecordSet->Update(varFields, varValues) );
pField->Release();
pFields->Release();
//Return to the edited record
//CADOBookmark cBookmark = m_piEmpRecordSet->GetLastModified();
//m_piEmpRecordSet->SetBookmark(cBookmark);
}
catch (HRESULT hr)
{
if (pField)
pField->Release();
if (pFields)
pFields->Release();
throw hr;
}
return ;
}
/////////////////////////////////////////////////////////////////////////////
// CEmpBiz support
//When the document is created, connect to the database and open the
//Employee recordset.
BOOL CEmpBiz::ConnectToDatabase()
{
CVarvarDataSource, varUserId, varPwd, varSQL;
HRESULThr;
CVarvNull(VT_ERROR, DISP_E_PARAMNOTFOUND);
VARIANT_BOOLvbEOF, vbBOF;
varDataSource= g_lpcwszSource;
varUserId= g_lpcwszUser;
varPwd= g_lpcwszPwd;
varSQL= g_lpcwszSQL;
//Open the database and the recordset
try
{
if ( m_piConnection == NULL || m_piEmpRecordSet == NULL)
{
THROW_ERR( CoInitialize(NULL) );
THROW_ERR( CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_INPROC_SERVER, IID_IADOConnection, (LPVOID *)&m_piConnection) );
THROW_ERR( m_piConnection->Open( varDataSource, varUserId, varPwd ) );
THROW_ERR( CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_INPROC_SERVER, IID_IADORecordset, (LPVOID *)&m_piEmpRecordSet) );
THROW_ERR( m_piEmpRecordSet->putref_ActiveConnection(m_piConnection) );
THROW_ERR( m_piEmpRecordSet->put_Source(varSQL) );
vNull.vt = VT_ERROR;
vNull.scode = DISP_E_PARAMNOTFOUND;
THROW_ERR( m_piEmpRecordSet->Open(vNull, vNull, adOpenKeyset, adLockOptimistic, adCmdText) );
//Check for empty record set.
THROW_ERR( m_piEmpRecordSet->get_EOF(&vbEOF) );
THROW_ERR( m_piEmpRecordSet->get_BOF(&vbBOF) );
if(vbEOF && vbBOF)
m_fRecordsetEmpty = TRUE;
else
m_fRecordsetEmpty = FALSE;
}
return TRUE;
}
catch (HRESULT hr)
{
TCHAR szBuf[256];
wsprintf(szBuf, _T("Error: %d \n"), hr);
AfxMessageBox(szBuf);
return (FALSE);
}
}