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

📄 irowsetupdateimpl.h

📁 The ATL OLE DB Provider templates only seem to support read-only rowsets and making them support upd
💻 H
字号:
#ifndef __I_ROWSET_UPDATE_IMPL__INCLUDED__
#define __I_ROWSET_UPDATE_IMPL__INCLUDED__

#include <atlcom.h>
#include <atldb.h>

#include "IRowsetChangeImpl.h"

///////////////////////////////////////////////////////////////////////////
// class IRowsetUpdateImpl

template <class T, class Storage>
class ATL_NO_VTABLE IRowsetUpdateImpl : public CRowsetChangeImpl<T, Storage, IRowsetUpdate>
{
public:

   /* this calls a pure virtual...
   IRowsetUpdateImpl() : m_bDelayedUpdate(CheckUpdateMode()) {} 
   */

   /* this is ambiguous...
   HRESULT FinalConstruct()
	{
      m_bDelayedUpdate = CheckUpdateMode();
   }
   */

   // This is ugly, but works...
   IRowsetUpdateImpl() : m_bCheckedUpdateMode(false), m_bDelayedUpdate(false) {}

   virtual bool DelayedUpdateMode() 
   { 
      if (!m_bCheckedUpdateMode)
      {
         m_bDelayedUpdate = CheckUpdateMode();
         m_bCheckedUpdateMode = true;
      }

      ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::DelayedUpdateMode - %s\n", (m_bDelayedUpdate ? "True" : "False"));

      return m_bDelayedUpdate; 
   }

   STDMETHOD(GetOriginalData)(
      HROW hRow,
      HACCESSOR hAccessor,
      void *pData)
   {
      ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::GetOriginalData()\n");
      // Get the data that hasn't been changed yet...

      T *pT = (T*)this;

      return pT->GetData(hRow, hAccessor, pData);
   }

   STDMETHOD(GetPendingRows)(
      HCHAPTER hReserved,
      DBPENDINGSTATUS dwRowStatus,
      ULONG *pcPendingRows,
      HROW **prgPendingRows,
      DBPENDINGSTATUS **prgPendingStatus)
   {
      ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::GetPendingRows()\n");

      return E_NOTIMPL;
   }

   STDMETHOD(GetRowStatus)(
      HCHAPTER hReserved,
      ULONG cRows,
      const HROW rghRows[],
      DBPENDINGSTATUS rgPendingStatus[])
   {
      ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::GetRowStatus()\n");

      if (hReserved != DB_NULL_HCHAPTER)
      {
         ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::GetRowStatus - (hReserved != DB_NULL_HCHAPTER())\n");
         return DB_E_BADCHAPTER;
      }

      if (cRows != 0 && (!rghRows || !rgPendingStatus))
      {
         ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::GetRowStatus - (cRows != 0 && (!rghREows || !rgPendingStatus))\n");
         return E_INVALIDARG;
      }

      bool bErrorsOccurred = false;

      for (size_t i = 0; i < cRows; i++)
      {
         T *pT = (T*)this;
      
         T::_HRowClass* pRow = 0; 

         if (rghRows[i] == 0 || (pRow = pT->m_rgRowHandles.Lookup((T::_HRowClass::KeyType)rghRows[i])) == NULL)
         {
            ATLTRACE2(atlTraceDBProvider, 0, "IRowsetChange::GetRowStatus - Bad row handle\n");
         
            rgPendingStatus[i] = DBROWSTATUS_E_INVALID;
            bErrorsOccurred = true;
         }
         else
         {
            // TODO: Should do this properly...
            rgPendingStatus[i] = DBPENDINGSTATUS_UNCHANGED;
         }

         ATLTRACE2(atlTraceDBProvider, 0, 
            "IRowsetUpdate::GetRowStatus - status of row: %d = %s\n",
            rghRows[i], ((rgPendingStatus[i] == DBPENDINGSTATUS_UNCHANGED) ? "Unchanged" : "INVALID"));
      }

      HRESULT hr = S_OK;

      if (bErrorsOccurred)
      {
         hr = DB_S_ERRORSOCCURRED;
      }
      
      return hr;
   }

   STDMETHOD(Undo)(
      HCHAPTER hReserved,
      ULONG cRows,
      const HROW rghRows[],
      ULONG *pcRows,
      HROW **prgRows,
      DBROWSTATUS **prgRowStatus)
   {
      ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::Undo()\n");

      return E_NOTIMPL;
   }

   STDMETHOD(Update)(
      HCHAPTER hReserved,
      ULONG cRows,
      const HROW rghRows[],
      ULONG *pcRows,
      HROW **prgRows,
      DBROWSTATUS **prgRowStatus)
   {
      ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::Update()\n");

      if (hReserved != DB_NULL_HCHAPTER)
      {
         ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::Update - (hReserved != DB_NULL_HCHAPTER())\n");
         return DB_E_BADCHAPTER;
      }

      if (cRows != 0 && !rghRows)
      {
         ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::Update - (cRows != 0 && !rghREows)\n");
         return E_INVALIDARG;
      }

      if (cRows == 0)
      {
         ATLTRACE2(atlTraceDBProvider, 0, "IRowsetUpdate::Update - (cRows == 0 - update all rows if required)\n");
      }
      else
      {
         // TODO
      }

      if (pcRows)
      {
         // number of rows we attempted to update

         *pcRows = 0;
      }

      if (prgRows)
      {
         // array of row handles in the update

         *prgRows = 0;

      }

      if (prgRowStatus)
      {
         *prgRowStatus = 0;

      }

      return S_OK;
      //return E_NOTIMPL;

      //return DB_E_ERRORSOCCURRED;
   }


   private :

      /*const*/ bool m_bDelayedUpdate;       // should be const, but we cant set it in the ctor...

      bool m_bCheckedUpdateMode;

      bool CheckUpdateMode()
      {
         T *pT = (T*)this;

	      CComQIPtr<IRowsetInfo> spProps = pT->GetUnknown();

	      CDBPropIDSet set(DBPROPSET_ROWSET);
	      set.AddPropertyID(DBPROP_IRowsetUpdate);
	      DBPROPSET* pPropSet = NULL;
	      ULONG ulPropSet = 0;
	      HRESULT hr;

	      if (spProps)
         {
		      hr = spProps->GetProperties(1, &set, &ulPropSet, &pPropSet);
         }

         bool bSupported = false;

	      if (pPropSet)
         {
		      CComVariant var = pPropSet->rgProperties[0].vValue;
		      CoTaskMemFree(pPropSet->rgProperties);
		      CoTaskMemFree(pPropSet);

		      if (SUCCEEDED(hr) && (var.boolVal ==  VARIANT_TRUE))
		      {
               bSupported = true;
            }
         }

         return bSupported;
      }
};

#endif // __I_ROWSET_UPDATE_IMPL__INCLUDED__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -