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

📄 proxyrowsetimpl.h

📁 The ATL OLE DB Provider templates only seem to support read-only rowsets and making them support upd
💻 H
📖 第 1 页 / 共 2 页
字号:
#ifndef __PROXY_ROWSET_IMPL__INCLUDED__
#define __PROXY_ROWSET_IMPL__INCLUDED__

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

#include <string>

///////////////////////////////////////////////////////////////////////////////
// CRowsetStorageProxy
// An ATL OLE DB Provider Storage template that forwards the required
// functionality to the Rowset object.
///////////////////////////////////////////////////////////////////////////////

template <class T>
class CRowsetStorageProxy
{
   public : 

      static ATLCOLUMNINFO* GetColumnInfo(T *pT, ULONG *pcCols)
      {
         ATLASSERT(pT);

         return pT->StorageProxy_GetColumnInfo(pcCols);
      }
};

///////////////////////////////////////////////////////////////////////////////
// CRowsetArrayTypeProxy
// An ATL OLE DB Provider ArrayType template that forwards the required
// functionality to the Rowset object.
///////////////////////////////////////////////////////////////////////////////

template <class T, class Storage>
class CRowsetArrayTypeProxy
{
   public :

      void Associate(T *pRowset)
      {
         m_pRowset = pRowset;
      }

      int GetSize() const
      {
         ATLASSERT(m_pRowset);

         return m_pRowset->ArrayProxy_GetSize();
      }

      unsigned char &operator[] (int nIndex) const
      {
         ATLASSERT(m_pRowset);

         return m_pRowset->ArrayProxy_IndexOperator(nIndex);
      }

      HRESULT Add(Storage &storage)
      {
         ATLASSERT(m_pRowset);

         return m_pRowset->ArrayProxy_Add(storage);
      }

   	HRESULT RemoveAt(int nIndex)
      {
         ATLASSERT(m_pRowset);

         return m_pRowset->ArrayProxy_RemoveAt(nIndex);
      }

      void RemoveAll()
      {
         ATLASSERT(m_pRowset);

         m_pRowset->ArrayProxy_RemoveAll();
      }

   private :

      T *m_pRowset;
};

///////////////////////////////////////////////////////////////////////////////
// CProxyRowsetImpl
// An ATL OLE DB Provider template that represents a Rowset which expects the 
// derived class to be responsible for storing the rowset data within it 
// (rather than working with the Storage and ArrayType classes). 
///////////////////////////////////////////////////////////////////////////////

template <
   class DataClass,
   class T, 
   class CreatorClass, 
   class Storage = CRowsetStorageProxy<T>, 
   class ArrayType = CRowsetArrayTypeProxy<T, Storage>,
   class RowClass = CSimpleRow,
   class RowsetInterface = IRowsetImpl < T, IRowset, RowClass> >
class CProxyRowsetImpl:
   public CRowsetImpl<T, Storage, CreatorClass, ArrayType, RowClass, RowsetInterface >
{
   public:

      friend Storage;
      friend ArrayType;

      typedef CreatorClass::_PropClass _PropClass ;

      typedef CProxyRowsetImpl<DataClass, T, CreatorClass, Storage, ArrayType, RowClass, RowsetInterface> ProxyRowsetClass;

      BEGIN_COM_MAP(CProxyRowsetImpl)
         COM_INTERFACE_ENTRY(IRowset)
         COM_INTERFACE_ENTRY_CHAIN(_RowsetBaseClass)
      END_COM_MAP()

      CProxyRowsetImpl();
      ~CProxyRowsetImpl();

      HRESULT ValidateCommandID(DBID* pTableID, DBID* pIndexID);

      HRESULT OnPropertyChanged(ULONG iCurSet, DBPROP* pDBProp);

      // override this from IRowsetImpl

      STDMETHOD(GetData)(
         HROW hRow,
         HACCESSOR hAccessor,
         void *pDstData);

      // Connect our rowset class to the data object that we represent.

      HRESULT LinkToObject(
         DataClass *pThis,   
         IUnknown *pUnkDataObject, 
         LONG* pcRowsAffected);


      // Not used but needs to be defined...

      HRESULT Execute(
         DBPARAMS * pParams, 
         LONG* pcRowsAffected);

   protected :

      virtual void GetColumnInformation(
         size_t column, 
         DBTYPE &dbType, 
         ULONG &size, 
         std::string &columnName, 
         DWORD &flags) = 0;

      virtual void GetColumnData(
         size_t row,
         size_t column,
         DBTYPE &dbType, 
         ULONG &size, 
         void *&pData,
         bool &bIsUpdatable) = 0;

      virtual size_t GetNumColumns() = 0;

      virtual size_t GetNumRows() const = 0;

      // default implementations of the following do nothing...
      virtual HRESULT AddRow();
      virtual HRESULT RemoveRow(int nIndex);
      virtual void RemoveAllRows();

      DataClass *m_pDataObject;
      IUnknown *m_pUnkDataObject;

      void InternalGetColumnData(
         size_t row,
         size_t column,
         DBTYPE &dbType, 
         ULONG &size, 
         void *&pData,
         bool &bIsUpdatable);

   private :

      wchar_t *ustrdup(const char *pIn);


      // Stuff needed because our Storage object forwards requests to us

      ATLCOLUMNINFO* StorageProxy_GetColumnInfo(ULONG *pcCols);

      // Stuff needed because our ArrayType object forwards requests to us

      int ArrayProxy_GetSize() const;

      unsigned char &ArrayProxy_IndexOperator(int nIndex) const;
      
      BOOL ArrayProxy_Add(Storage &storage);
	   
      BOOL ArrayProxy_RemoveAt(int nIndex);
      
      void ArrayProxy_RemoveAll();

      // Cached column information

      void BuildColumnInfo();
      bool BookmarksRequired();

      ATLCOLUMNINFO *m_pColumnInfo;
      ULONG m_NumCols;
};

///////////////////////////////////////////////////////////////////////////////
// Construction and destruction...
///////////////////////////////////////////////////////////////////////////////

template <class DataClass, class T, class CreatorClass, class Storage, class ArrayType, class RowClass, class RowsetInterface>
CProxyRowsetImpl<DataClass, T, CreatorClass, Storage, ArrayType, RowClass, RowsetInterface>::CProxyRowsetImpl()
   :  m_pDataObject(0),
      m_pUnkDataObject(0),
      m_pColumnInfo(0),
      m_NumCols(0)
{
   m_rgRowData.Associate((T*)this);
}

template <class DataClass, class T, class CreatorClass, class Storage, class ArrayType, class RowClass, class RowsetInterface>
CProxyRowsetImpl<DataClass, T, CreatorClass, Storage, ArrayType, RowClass, RowsetInterface>::~CProxyRowsetImpl()
{
   if (m_pColumnInfo)
   {
      for (size_t i = 0; i < m_NumCols; i++)
      {
         delete [] m_pColumnInfo[i].pwszName;
      }

      delete [] m_pColumnInfo;

      m_pColumnInfo = 0;
      m_NumCols = 0;
   }

   if (m_pUnkDataObject)
   {
      m_pUnkDataObject->Release();
      m_pUnkDataObject = 0;
   }

   m_pDataObject = 0;

}

///////////////////////////////////////////////////////////////////////////////
// 
///////////////////////////////////////////////////////////////////////////////

template <class DataClass, class T, class CreatorClass, class Storage, class ArrayType, class RowClass, class RowsetInterface>
HRESULT CProxyRowsetImpl<DataClass, T, CreatorClass, Storage, ArrayType, RowClass, RowsetInterface>::ValidateCommandID(
   DBID* pTableID, 
   DBID* pIndexID)
{
	HRESULT hr = _RowsetBaseClass::ValidateCommandID(pTableID, pIndexID);
   
   if (hr != S_OK)
   {
		return hr;
   }

	if (pIndexID != NULL)
   {
		return DB_E_NOINDEX;    // We don't support indexes
   }
   
	return S_OK;
}

template <class DataClass, class T, class CreatorClass, class Storage, class ArrayType, class RowClass, class RowsetInterface>
HRESULT CProxyRowsetImpl<DataClass, T, CreatorClass, Storage, ArrayType, RowClass, RowsetInterface>::OnPropertyChanged(
   ULONG iCurSet, 
   DBPROP* pDBProp)
{
	ATLASSERT(pDBProp != NULL);

	DWORD dwPropertyID = pDBProp->dwPropertyID;

	if (dwPropertyID == DBPROP_IRowsetLocate ||
		dwPropertyID == DBPROP_LITERALBOOKMARKS ||
		dwPropertyID == DBPROP_ORDEREDBOOKMARKS)
	{
		CComVariant var = pDBProp->vValue;

		if (var.boolVal == VARIANT_TRUE)
		{
			// Set the bookmarks property as these are chained
			CComVariant bookVar(true);
			CDBPropSet set(DBPROPSET_ROWSET);
			set.AddProperty(DBPROP_BOOKMARKS, bookVar);

			// If you set IRowsetLocate to true, then the rowset can
			// handle backward scrolling
			if (dwPropertyID == DBPROP_IRowsetLocate)
         {
				set.AddProperty(DBPROP_CANSCROLLBACKWARDS, bookVar);
         }

			const GUID* ppGuid[1];
			ppGuid[0] = &DBPROPSET_ROWSET;

			return SetProperties(0, 1, &set, 1, ppGuid);
		}
	}

	return S_OK;
}

///////////////////////////////////////////////////////////////////////////////
// 
///////////////////////////////////////////////////////////////////////////////

template <class DataClass, class T, class CreatorClass, class Storage, class ArrayType, class RowClass, class RowsetInterface>
bool CProxyRowsetImpl<DataClass, T, CreatorClass, Storage, ArrayType, RowClass, RowsetInterface>::BookmarksRequired()
{
	CComQIPtr<IRowsetInfo> spProps(this);

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

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

	// Check the property flag for bookmarks, if it is set, set the zero ordinal
	// entry in the column map with the bookmark information.

   bool bRequired = false;

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

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

   return bRequired;
}

template <class DataClass, class T, class CreatorClass, class Storage, class ArrayType, class RowClass, class RowsetInterface>
HRESULT CProxyRowsetImpl<DataClass, T, CreatorClass, Storage, ArrayType, RowClass, RowsetInterface>::LinkToObject(
   DataClass *pDataObject,   
   IUnknown *pUnkDataObject, 
   LONG* pcRowsAffected)
{
   if (!pDataObject || !pUnkDataObject)
   {
      return E_INVALIDARG;
   }

   ObjectLock lock(this);

   m_pDataObject = pDataObject;

   if (m_pUnkDataObject)
   {
      m_pUnkDataObject->Release();
   }

   m_pUnkDataObject = pUnkDataObject;
   m_pUnkDataObject->AddRef();

⌨️ 快捷键说明

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