home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / ado / employee / empbiz.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-18  |  12.3 KB  |  572 lines

  1. // EmpBiz.cpp : implementation file
  2. //
  3. #define INITGUID
  4. #include "stdafx.h"
  5. #include "Emp.h"
  6. #include "EmpBiz.h"
  7.  
  8. #ifdef _DEBUG
  9. //#define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13.  
  14. #define THROW_ERR(exp)    if (FAILED(hr = (exp))) throw hr
  15.  
  16. const LPCWSTR g_lpcwszSource = L"OLE_DB_NWind_Jet;";
  17. const LPCWSTR g_lpcwszUser = L"Admin";
  18. const LPCWSTR g_lpcwszPwd = L"";
  19. const LPCWSTR g_lpcwszSQL = L"select EmployeeId, LastName, FirstName, Title, HomePhone from Employees";
  20.  
  21. static bool fResetFilter = false;
  22.  
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CEmpBiz 
  25.  
  26. CEmpBiz::CEmpBiz()
  27. {
  28.     m_piConnection = NULL;
  29.     m_piEmpRecordSet = NULL; 
  30.     m_fConnected = FALSE;
  31.     m_fRecordsetEmpty = TRUE;
  32. }
  33.  
  34. CEmpBiz::~CEmpBiz()
  35. {    
  36.     if ( m_piConnection != NULL )
  37.         m_piConnection->Release();                     
  38.     if ( m_piEmpRecordSet != NULL )
  39.         m_piEmpRecordSet->Release();                     
  40.     m_varLastGoodRecord.Clear();
  41.     m_piConnection = NULL;
  42.     m_piEmpRecordSet = NULL;
  43. }
  44.  
  45.  
  46.  
  47. long CEmpBiz::GetEmployeeId() 
  48. {
  49.     HRESULT            hr;
  50.     COleVariant        vFldName, vID;
  51.     
  52.     if (!m_fConnected)
  53.         return 0;
  54.  
  55.     //Watch for empty recordset
  56.     if(m_fRecordsetEmpty)
  57.         return 0;
  58.  
  59.     vFldName.bstrVal = CString(EMP_EMPLOYEE_ID).AllocSysString();
  60.     vFldName.vt = VT_BSTR;
  61.     THROW_ERR(     m_piEmpRecordSet->get_Collect(vFldName, vID)    );
  62.     
  63.     return VTOLONG(vID);
  64. }
  65.  
  66.         
  67. CString CEmpBiz::GetFirstName() 
  68. {
  69.     HRESULT            hr;
  70.     COleVariant        vFldName, vFirstName;
  71.  
  72.      if (!m_fConnected)
  73.         return "";
  74.  
  75.     //Watch for empty recordset
  76.     if(m_fRecordsetEmpty)
  77.         return "";
  78.  
  79.     vFldName.bstrVal = CString(EMP_FIRST_NAME).AllocSysString();
  80.     vFldName.vt = VT_BSTR;
  81.     THROW_ERR(    m_piEmpRecordSet->get_Collect(vFldName, vFirstName) );
  82.     
  83.     return VTOCSTR(vFirstName);
  84. }
  85.                       
  86. CString CEmpBiz::GetLastName() 
  87. {
  88.     HRESULT            hr;
  89.     COleVariant        vFldName, vLastName;
  90.  
  91.      if (!m_fConnected)
  92.         return "";
  93.  
  94.     //Watch for empty recordset
  95.     if(m_fRecordsetEmpty)
  96.         return "";
  97.  
  98.     vFldName.bstrVal = CString(EMP_LAST_NAME).AllocSysString();
  99.     vFldName.vt = VT_BSTR;
  100.     THROW_ERR(    m_piEmpRecordSet->get_Collect(vFldName, vLastName) );
  101.     
  102.     return VTOCSTR(vLastName);
  103. }
  104.                              
  105. CString CEmpBiz::GetHomePhone() 
  106. {
  107.     HRESULT            hr;
  108.     COleVariant        vFldName, vHomePhone;
  109.  
  110.      if (!m_fConnected)
  111.         return "";
  112.  
  113.     //Watch for empty recordset
  114.     if(m_fRecordsetEmpty)
  115.         return "";
  116.  
  117.     vFldName.bstrVal = CString(EMP_HOME_PHONE).AllocSysString();
  118.     vFldName.vt = VT_BSTR;
  119.     THROW_ERR(    m_piEmpRecordSet->get_Collect(vFldName, vHomePhone) );
  120.     
  121.     return VTOCSTR(vHomePhone);
  122. }
  123.                            
  124. CString CEmpBiz::GetTitle() 
  125. {
  126.     HRESULT            hr;
  127.     COleVariant        vFldName, vTitle;
  128.  
  129.      if (!m_fConnected)
  130.         return "";
  131.  
  132.     //Watch for empty recordset
  133.     if(m_fRecordsetEmpty)
  134.         return "";
  135.  
  136.     vFldName.bstrVal = CString(EMP_TITLE).AllocSysString();
  137.     vFldName.vt = VT_BSTR;
  138.     THROW_ERR(    m_piEmpRecordSet->get_Collect(vFldName, vTitle) );
  139.     
  140.     return VTOCSTR(vTitle);
  141. }
  142.  
  143.           
  144.  
  145. BOOL CEmpBiz::IsAddMode() 
  146. {
  147.     HRESULT            hr;
  148.      EditModeEnum    lEditMode;
  149.  
  150.     THROW_ERR(    m_piEmpRecordSet->get_EditMode(&lEditMode) );
  151.  
  152.     return lEditMode == adEditAdd ;
  153. }
  154.  
  155.  
  156. void CEmpBiz::AddRecord() 
  157. {
  158.     // TODO: Add your control notification handler code here
  159.     HRESULT            hr;
  160.     VARIANT            rgvFields;
  161.     VARIANT            rgvValues;
  162.  
  163.     if (!m_fConnected)
  164.         return;
  165.  
  166.     ClearFilter() ;
  167.  
  168.     //Watch for empty recordset
  169.     if(!m_fRecordsetEmpty && !IsAddMode() )
  170.     {
  171.         //Remember where we were before adding in case the user
  172.         //cancels and we have to return
  173.         THROW_ERR(    m_piEmpRecordSet->get_Bookmark(m_varLastGoodRecord) );
  174.     }
  175.  
  176.     rgvFields.vt = VT_ERROR;
  177.     rgvFields.scode = DISP_E_PARAMNOTFOUND;
  178.  
  179.     rgvValues.vt = VT_ERROR;
  180.     rgvValues.scode = DISP_E_PARAMNOTFOUND;
  181.  
  182.     THROW_ERR(    m_piEmpRecordSet->AddNew(rgvFields, rgvValues) );
  183. //    THROW_ERR(     m_piEmpRecordSet->Update(rgvFields, rgvValues) );
  184.  
  185.     m_fRecordsetEmpty = FALSE;
  186.     return ;
  187. }
  188.  
  189. void CEmpBiz::CancelPendingAdd()
  190. {
  191.     HRESULT hr;
  192.     THROW_ERR(     m_piEmpRecordSet->CancelUpdate() );
  193.     THROW_ERR(     m_piEmpRecordSet->put_Bookmark(m_varLastGoodRecord) );
  194. }
  195.  
  196. void CEmpBiz::DeleteRecord() 
  197. {
  198.     // TODO: Add your control notification handler code here
  199.     HRESULT            hr;
  200.      EditModeEnum    lEditMode;
  201.     VARIANT_BOOL    vbEOF, vbBOF;
  202.  
  203.     //Watch for empty recordset
  204.     if (!m_fConnected || m_fRecordsetEmpty)
  205.         return;
  206.  
  207.     //Delete method depends on current mode
  208.     THROW_ERR(    m_piEmpRecordSet->get_EditMode(&lEditMode) );
  209.  
  210.     switch (lEditMode)
  211.     {
  212.         case adEditNone: // Just delete it
  213.         {
  214.             THROW_ERR(     m_piEmpRecordSet->Delete(adAffectCurrent) );
  215.             THROW_ERR(     m_piEmpRecordSet->MoveNext() );
  216.             //Watch for end of record set
  217.             THROW_ERR(     m_piEmpRecordSet->get_EOF(&vbEOF) );
  218.             if(vbEOF)
  219.             {
  220.                 THROW_ERR(    m_piEmpRecordSet->MovePrevious() );
  221.                 //Check for empty record set.
  222.                 THROW_ERR(     m_piEmpRecordSet->get_BOF(&vbBOF) );
  223.                 if(vbBOF)
  224.                     m_fRecordsetEmpty  = TRUE;
  225.             }
  226.             break;
  227.         }
  228.  
  229.         case adEditInProgress: //Forget changes
  230.         {
  231.             THROW_ERR(     m_piEmpRecordSet->CancelUpdate() );
  232.             THROW_ERR(     m_piEmpRecordSet->Delete(adAffectCurrent) );
  233.             THROW_ERR(     m_piEmpRecordSet->MoveFirst() );
  234.             break;
  235.         }
  236.  
  237.         case adEditAdd: //If new record, go back to last known
  238.         {
  239.             THROW_ERR(     m_piEmpRecordSet->CancelUpdate() );
  240.             THROW_ERR(     m_piEmpRecordSet->put_Bookmark(m_varLastGoodRecord) );
  241.         }
  242.     }
  243.  
  244.     return ;
  245. }
  246.  
  247. BOOL CEmpBiz::MoveNext() 
  248. {
  249.     // TODO: Add your control notification handler code here
  250.     HRESULT        hr;
  251.     VARIANT_BOOL vbEOF;
  252.  
  253.     if (!m_fConnected || m_fRecordsetEmpty)
  254.         return FALSE;
  255.  
  256.     if (fResetFilter)
  257.         ClearFilter();
  258.  
  259.     THROW_ERR(    m_piEmpRecordSet->MoveNext() );
  260.  
  261.     //Watch for end of record set
  262.     THROW_ERR(    m_piEmpRecordSet->get_EOF(&vbEOF) );
  263.     if(vbEOF)
  264.     {
  265.         THROW_ERR(    m_piEmpRecordSet->MovePrevious() );
  266.         return FALSE;
  267.     }
  268.     else
  269.     {
  270.         return TRUE;
  271.     }
  272. }
  273.  
  274.  
  275.  
  276. BOOL CEmpBiz::MovePrevious() 
  277. {
  278.     // TODO: Add your control notification handler code here
  279.     HRESULT        hr;
  280.     VARIANT_BOOL vbBOF;
  281.  
  282.     if (!m_fConnected || m_fRecordsetEmpty)
  283.         return FALSE;
  284.  
  285.     if (fResetFilter)
  286.         ClearFilter();
  287.  
  288.     THROW_ERR(    m_piEmpRecordSet->MovePrevious() );
  289.  
  290.     //Watch for beginning of recordset
  291.     THROW_ERR(    m_piEmpRecordSet->get_BOF(&vbBOF) );
  292.     if(vbBOF)
  293.     {
  294.         THROW_ERR(    m_piEmpRecordSet->MoveNext() );             
  295.         return FALSE;
  296.     }
  297.     else
  298.     {            
  299.         return TRUE;
  300.     }
  301. }
  302.  
  303.  
  304.  
  305. BOOL CEmpBiz::MoveFirst() 
  306. {
  307.     // TODO: Add your control notification handler code here
  308.     HRESULT        hr;
  309.     VARIANT_BOOL vbBOF;
  310.  
  311.     if (!m_fConnected || m_fRecordsetEmpty)
  312.         return FALSE;
  313.  
  314.     if (fResetFilter)
  315.         ClearFilter();
  316.  
  317.     THROW_ERR(    m_piEmpRecordSet->MoveFirst() );
  318.  
  319.     //Watch for beginning of recordset
  320.     THROW_ERR(    m_piEmpRecordSet->get_BOF(&vbBOF) );
  321.     if(vbBOF)
  322.     {
  323.         return FALSE;
  324.     }
  325.     else
  326.     {            
  327.         return TRUE;
  328.     }
  329. }
  330.  
  331.  
  332.  
  333. BOOL CEmpBiz::MoveLast() 
  334. {
  335.     // TODO: Add your control notification handler code here
  336.     HRESULT        hr;
  337.     VARIANT_BOOL vbEOF;
  338.  
  339.     if (!m_fConnected || m_fRecordsetEmpty)
  340.         return FALSE;
  341.  
  342.     if (fResetFilter)
  343.         ClearFilter();
  344.  
  345.     THROW_ERR(    m_piEmpRecordSet->MoveLast() );
  346.  
  347.     //Watch for beginning of recordset
  348.     THROW_ERR(    m_piEmpRecordSet->get_BOF(&vbEOF) );
  349.     if(vbEOF)
  350.     {
  351.         return FALSE;
  352.     }
  353.     else
  354.     {            
  355.         return TRUE;
  356.     }
  357. }
  358.  
  359.  
  360. BOOL CEmpBiz::FindForward(CString strCriteria) 
  361. {
  362.     HRESULT            hr;
  363.     VARIANT_BOOL    vbEOF;
  364.     COleVariant        v;
  365.  
  366.     if (!m_fConnected || m_fRecordsetEmpty)
  367.         return FALSE;
  368.  
  369.     THROW_ERR(    m_piEmpRecordSet->get_Filter(&v) );
  370.     if ( v.vt != VT_BSTR || strCriteria !=    v.bstrVal )
  371.     {
  372.         v.vt = VT_BSTR;
  373.         v.bstrVal = strCriteria.AllocSysString();
  374.         THROW_ERR(  m_piEmpRecordSet->put_Filter(v) );
  375.         fResetFilter = true;
  376.     }
  377.     else
  378.     {
  379.         THROW_ERR( m_piEmpRecordSet->MoveNext() );
  380.     }
  381.         
  382.     //Watch for ending of recordset
  383.     THROW_ERR(    m_piEmpRecordSet->get_EOF(&vbEOF));
  384.     if(vbEOF)
  385.     {                       
  386.         ClearFilter() ;
  387.         THROW_ERR( m_piEmpRecordSet->MoveLast() );
  388.  
  389.         return FALSE;
  390.     }
  391.     else
  392.     {            
  393.         return TRUE;
  394.     }
  395. }
  396.  
  397.  
  398. void CEmpBiz::ClearFilter() 
  399. {
  400.     HRESULT        hr;
  401.     VARIANT        v;
  402.  
  403.     if ( !m_fRecordsetEmpty)
  404.     {
  405.         v.vt = VT_I2;
  406.         v.iVal = adFilterNone;
  407.         THROW_ERR(    m_piEmpRecordSet->put_Filter(v) );
  408.         fResetFilter = false;
  409.     }
  410. }
  411.  
  412.       
  413.  
  414.  
  415. //
  416. //Update record in the database
  417. //
  418. void CEmpBiz::UpdateEmpRec(CString &strFirstName, 
  419.             CString &strHomePhone, CString &strLastName,
  420.             CString &strTitle)
  421. {
  422.     HRESULT        hr;
  423.     VARIANT        varFields;           
  424.     VARIANT        varValues;
  425.     WCHAR        *columnNames[4] = { L"firstName", L"Lastname", L"title", L"homePhone"};
  426.     ADOFields    *pFields = NULL;
  427.     ADOField    *pField = NULL;
  428.     CVar        varIndex(VT_BSTR);
  429.     COleVariant    varFieldVal;
  430.  
  431.     if  (m_fRecordsetEmpty)
  432.         return;
  433.  
  434.     varFields.vt = VT_ERROR;
  435.     varFields.scode = DISP_E_PARAMNOTFOUND;
  436.     varValues.vt = VT_ERROR;
  437.     varValues.scode = DISP_E_PARAMNOTFOUND;
  438.     
  439.     try
  440.     {
  441.         // get the fields interface
  442.         THROW_ERR(     m_piEmpRecordSet->get_Fields(&pFields) );
  443.  
  444.         varIndex = SysAllocString(columnNames[0]) ;
  445.         THROW_ERR(     pFields->get_Item(varIndex, &pField) );
  446.         varFieldVal.vt = VT_BSTR;
  447.         varFieldVal.bstrVal = strFirstName.AllocSysString();
  448.         THROW_ERR(     pField->put_Value(varFieldVal) );
  449.         varFieldVal.Clear();
  450.  
  451.         varIndex = SysAllocString(columnNames[1]) ;
  452.         THROW_ERR(     pFields->get_Item(varIndex, &pField) );
  453.         varFieldVal.vt = VT_BSTR;
  454.         varFieldVal.bstrVal = strLastName.AllocSysString();
  455.         THROW_ERR(     pField->put_Value(varFieldVal) );
  456.         varFieldVal.Clear();
  457.  
  458.         varIndex = SysAllocString(columnNames[2]) ;
  459.         THROW_ERR(     pFields->get_Item(varIndex, &pField) );
  460.         varFieldVal.vt = VT_BSTR;
  461.         varFieldVal.bstrVal = strTitle.AllocSysString();
  462.         THROW_ERR(     pField->put_Value(varFieldVal) );
  463.         varFieldVal.Clear();
  464.  
  465.         varIndex = SysAllocString(columnNames[3]) ;
  466.         THROW_ERR(     pFields->get_Item(varIndex, &pField) );
  467.         varFieldVal.vt = VT_BSTR;
  468.         varFieldVal.bstrVal = strHomePhone.AllocSysString();
  469.         THROW_ERR(     pField->put_Value(varFieldVal) );
  470.         varFieldVal.Clear();
  471.  
  472.         //Commit the changes       
  473.         THROW_ERR(     m_piEmpRecordSet->Update(varFields, varValues) );
  474.         
  475.         pField->Release();
  476.         pFields->Release();
  477.  
  478.         //Return to the edited record
  479.         //CADOBookmark cBookmark = m_piEmpRecordSet->GetLastModified();
  480.         //m_piEmpRecordSet->SetBookmark(cBookmark);
  481.     }
  482.     catch (HRESULT hr)
  483.     {
  484.         if (pField)
  485.             pField->Release();
  486.         if (pFields)
  487.             pFields->Release();
  488.         throw hr;
  489.     }
  490.     return ;
  491. }
  492.  
  493.  
  494. /////////////////////////////////////////////////////////////////////////////
  495. // CEmpBiz support 
  496.  
  497. //When the document is created, connect to the database and open the
  498. //Employee recordset.
  499. BOOL CEmpBiz::ConnectToDatabase()
  500. {
  501.  
  502.     CVar        varDataSource, varUserId, varPwd, varSQL;
  503.     HRESULT        hr;
  504.     CVar        vNull(VT_ERROR, DISP_E_PARAMNOTFOUND);
  505.     VARIANT_BOOL    vbEOF, vbBOF;
  506.  
  507.     varDataSource    = g_lpcwszSource;
  508.     varUserId        = g_lpcwszUser;
  509.     varPwd            = g_lpcwszPwd;
  510.     varSQL            = g_lpcwszSQL;
  511.  
  512.     //Open the database and the recordset
  513.     try
  514.     {
  515.         if ( m_piConnection == NULL || m_piEmpRecordSet == NULL)
  516.         {
  517.             THROW_ERR(      CoInitialize(NULL) );
  518.             THROW_ERR(      CoCreateInstance(CLSID_CADOConnection, NULL, CLSCTX_INPROC_SERVER, IID_IADOConnection, (LPVOID *)&m_piConnection) );
  519.             THROW_ERR(      m_piConnection->Open( varDataSource, varUserId, varPwd, adOpenUnspecified ) );
  520.  
  521.             THROW_ERR(      CoCreateInstance(CLSID_CADORecordset, NULL, CLSCTX_INPROC_SERVER, IID_IADORecordset, (LPVOID *)&m_piEmpRecordSet) );
  522.             THROW_ERR(      m_piEmpRecordSet->putref_ActiveConnection(m_piConnection) );    
  523.             THROW_ERR(      m_piEmpRecordSet->put_Source(varSQL) );         
  524.  
  525.             vNull.vt = VT_ERROR;
  526.             vNull.scode = DISP_E_PARAMNOTFOUND;
  527.             THROW_ERR(      m_piEmpRecordSet->Open(vNull, vNull, adOpenKeyset, adLockOptimistic, adCmdText) );        
  528.  
  529.             //Check for empty record set.
  530.             THROW_ERR(     m_piEmpRecordSet->get_EOF(&vbEOF) );
  531.             THROW_ERR(     m_piEmpRecordSet->get_BOF(&vbBOF) );
  532.             if(vbEOF && vbBOF)
  533.                 m_fRecordsetEmpty  = TRUE;
  534.             else
  535.                 m_fRecordsetEmpty  = FALSE;
  536.         }
  537.  
  538.         return TRUE;
  539.     }
  540.     catch (HRESULT hr)
  541.     {
  542.         PopupErrorMessage(hr);
  543.         return (FALSE);
  544.     }
  545. }
  546.  
  547. void PopupErrorMessage(HRESULT hr)
  548. {
  549.     IErrorInfo *pei = NULL;
  550.     if (::GetErrorInfo(0, &pei) == S_OK)
  551.     {
  552.         BSTR err;
  553.         int wlen = 0;
  554.         TCHAR szBuff[1024];
  555.  
  556.         pei->GetDescription(&err);
  557.         pei->Release();
  558.         wlen = WideCharToMultiByte(CP_ACP, 0, err, SysStringLen(err), szBuff, 1023, NULL, NULL);
  559.         SysFreeString(err);
  560.         if (wlen > 0)
  561.         {
  562.             szBuff[wlen] = '\0';
  563.             AfxMessageBox(szBuff);
  564.             return;
  565.         }
  566.     }
  567.  
  568.     TCHAR szBuf[256];
  569.     wsprintf(szBuf, _T("Error: %X \n"), hr);
  570.     AfxMessageBox(szBuf);
  571. }
  572.