📄 irowsetlocateimpl.h
字号:
#ifndef __I_ROWSET_LOCATE_IMPL__INCLUDED__
#define __I_ROWSET_LOCATE_IMPL__INCLUDED__
#include <atlcom.h>
#include <atldb.h>
template <
class T,
class Base,
class RowClass = CSimpleRow,
class MapClass = CSimpleMap < RowClass::KeyType, RowClass* > >
class ATL_NO_VTABLE CRowsetLocateImpl ;
template <
class T,
class RowClass = CSimpleRow,
class MapClass = CSimpleMap < RowClass::KeyType, RowClass* > >
class ATL_NO_VTABLE IRowsetLocateImpl : public CRowsetLocateImpl<T, IRowsetLocate, RowClass, MapClass>
{
};
template <
class T,
class Base,
class RowClass = CSimpleRow,
class MapClass = CSimpleMap < RowClass::KeyType, RowClass* > >
class ATL_NO_VTABLE CRowsetLocateImpl : public IRowsetImpl<T, Base, RowClass, MapClass>
{
public:
STDMETHOD (Compare)(HCHAPTER hReserved, ULONG cbBookmark1,
const BYTE * pBookmark1, ULONG cbBookmark2, const BYTE * pBookmark2,
DBCOMPARE * pComparison)
{
ATLTRACE2(atlTraceDBProvider, 0, "IRowsetLocateImpl::Compare\n");
HRESULT hr = ValidateBookmark(cbBookmark1, pBookmark1);
if (hr != S_OK)
{
return hr;
}
hr = ValidateBookmark(cbBookmark2, pBookmark2);
if (hr != S_OK)
{
return hr;
}
// Return the value based on the bookmark values
if (*(DWORD*)pBookmark1 == *(DWORD*)pBookmark2)
{
*pComparison = DBCOMPARE_EQ;
}
if (*(DWORD*)pBookmark1 < *(DWORD*)pBookmark2)
{
*pComparison = DBCOMPARE_LT;
}
if (*(DWORD*)pBookmark1 > *(DWORD*)pBookmark2)
{
*pComparison = DBCOMPARE_GT;
}
return S_OK;
}
STDMETHOD (GetRowsAt)(HWATCHREGION hReserved1, HCHAPTER hReserved2,
ULONG cbBookmark, const BYTE * pBookmark, LONG lRowsOffset,
LONG cRows, ULONG * pcRowsObtained, HROW ** prghRows)
{
ATLTRACE2(atlTraceDBProvider, 0, "IRowsetLocateImpl::GetRowsAt\n");
T* pT = (T*)this;
// Check bookmark
HRESULT hr = ValidateBookmark(cbBookmark, pBookmark);
if (hr != S_OK)
{
return hr;
}
// Check the other pointers
if (pcRowsObtained == NULL || prghRows == NULL)
{
return E_INVALIDARG;
}
// Set the current row position to the bookmark. Handle any
// normal values
pT->Lock();
// We need to handle the offset as the start position is defined
// as the bookmark + offset. If the offset is negative, and we
// do not have m_bCanScrollBack then return an error. The
// GetNextRows function handles the case where cRows is negative
// and we don't have m_bCanFetchBack set.
if (lRowsOffset < 0 && !pT->m_bCanScrollBack)
{
pT->Unlock();
return DB_E_CANTSCROLLBACKWARDS;
}
LONG iRowsetTemp = pT->m_iRowset; // Cache the current rowset
pT->m_iRowset = *(DWORD*)pBookmark;
if ((cbBookmark == 1) && (*pBookmark == DBBMK_FIRST))
{
pT->m_iRowset = 1;
}
if ((cbBookmark == 1) && (*pBookmark == DBBMK_LAST))
{
pT->m_iRowset = pT->m_rgRowData.GetSize();
}
// Set the start position to m_iRowset + lRowsOffset
pT->m_iRowset += lRowsOffset;
if (lRowsOffset >= 0)
{
(cRows >= 0) ? pT->m_iRowset -= 1 : pT->m_iRowset +=0;
}
else
{
(cRows >= 0) ? pT->m_iRowset -= 1 : pT->m_iRowset +=0;
// (lRowsOffset >= 0) ? m_iRowset -= 1 : m_iRowset += 1;
}
if (pT->m_iRowset < 0 || pT->m_iRowset > (DWORD)pT->m_rgRowData.GetSize())
{
pT->m_iRowset = iRowsetTemp;
pT->Unlock();
return DB_E_BADSTARTPOSITION;
}
// Call IRowsetImpl::GetNextRows to actually get the rows.
hr = pT->GetNextRows(hReserved2, 0, cRows, pcRowsObtained, prghRows);
pT->m_iRowset = iRowsetTemp;
pT->Unlock();
return hr;
}
STDMETHOD (GetRowsByBookmark)(HCHAPTER hReserved, ULONG cRows,
const ULONG rgcbBookmarks[], const BYTE * rgpBookmarks[],
HROW rghRows[], DBROWSTATUS rgRowStatus[])
{
HRESULT hr = S_OK;
ATLTRACE2(atlTraceDBProvider, 0, "IRowsetLocateImpl::GetRowsByBookmark\n");
T* pT = (T*)this;
if (rgcbBookmarks == NULL || rgpBookmarks == NULL || rghRows == NULL)
{
return E_INVALIDARG;
}
if (cRows == 0)
{
return S_OK; // No rows fetched in this case.
}
bool bErrors = false;
pT->Lock();
for (ULONG l=0; l<cRows; l++)
{
// Validate each bookmark before fetching the row. Note, it is
// an error for the bookmark to be one of the standard values
hr = ValidateBookmark(rgcbBookmarks[l], rgpBookmarks[l]);
if (hr != S_OK)
{
bErrors = TRUE;
if (rgRowStatus != NULL)
{
rgRowStatus[l] = DBROWSTATUS_E_INVALID;
continue;
}
}
// Fetch the row, we now that it is a valid row after validation.
ULONG ulRowsObtained = 0;
if (pT->CreateRow((long)*rgpBookmarks[l], ulRowsObtained, &rghRows[l]) != S_OK)
{
bErrors = TRUE;
}
else
{
if (rgRowStatus != NULL)
{
rgRowStatus[l] = DBROWSTATUS_S_OK;
}
}
}
pT->Unlock();
if (bErrors)
{
return DB_S_ERRORSOCCURRED;
}
return hr;
}
STDMETHOD (Hash)(HCHAPTER hReserved, ULONG cBookmarks,
const ULONG rgcbBookmarks[], const BYTE * rgpBookmarks[],
DWORD rgHashedValues[], DBROWSTATUS rgBookmarkStatus[])
{
ATLTRACENOTIMPL("IRowsetLocateImpl::Hash");
}
// Implementation
protected:
HRESULT ValidateBookmark(ULONG cbBookmark, const BYTE* pBookmark)
{
T* pT = (T*)this;
if (cbBookmark == 0 || pBookmark == NULL)
{
return E_INVALIDARG;
}
// All of our bookmarks are DWORDs, if they are anything other than
// sizeof(DWORD) then we have an invalid bookmark
if ((cbBookmark != sizeof(DWORD)) && (cbBookmark != 1))
{
ATLTRACE("Bookmarks are invalid length, should be DWORDs");
return DB_E_BADBOOKMARK;
}
// If the contents of our bookmarks are less than 0 or greater than
// rowcount, then they are invalid
UINT nRows = pT->m_rgRowData.GetSize();
if ((*(DWORD*)pBookmark <= 0 || *(DWORD*)pBookmark > nRows)
&& *pBookmark != DBBMK_FIRST && *pBookmark != DBBMK_LAST)
{
ATLTRACE("Bookmark has invalid range");
return DB_E_BADBOOKMARK;
}
return S_OK;
}
};
#endif // __I_ROWSET_LOCATE_IMPL__INCLUDED__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -