📄 proxyrowsetimpl.h
字号:
#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 + -