EMPBIZ.CPP
// 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); 
} 
}