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);
}
}