Sizin uygulanması tamamlamak için IRowsetLocate arabirimi, yer imleri uygulamalıdır. Yer imleri, verilere hızlı erişim sağlayan Endeksleri içine satır kümesi vardır. Sağlayıcı ne olabilir yer imleri benzersiz olarak belirleyen bir satır tanımlayın. Bu örnek, dizin kullanır m_rgAgentInfo dizi.
Sağlayıcı, yer işareti herhangi bir biçimde alabilirsiniz. Yer işareti geçerli olduğundan emin olmak için:
CAgentMan , dwBookmark girişinin dwordolmasını belirtir. Tek bayt uzunluğu için özel yer DBMRK_FIRST ve dbmrk_lastkullanılır.)Hem yer imleri (biri her dize) doğrulamak sonra iki yer alır ve bir daha, değerinden az olup olmadığını belirler, karşılaştırma yöntemi veya başka birine eşit.
Satırlar getirmek için GetRowsAt ve GetRowsByBookmark işlevleri uygulamak.
GetRowsAt inşaat aynı IRowset::GetNextRows yöntemi bunun dışında verileri almak için bir yer imi kullanır. O yer imi doğrular ve sonra satır almak için IRowsetImpl::GetNextRows çağırır.
GetRowsByBookmark yerlerde bir numaradan bir satır getirir. Belirli satırlar getirmek için kullanın. GetRowsByBookmark her yer imleri doğrular ve gerekirse yeni bir satır oluşturur arama IRowsetImpl::CreateRowtarafından satır getirir. Tarafından işaret dizideki satır döndürdürghRows.
(Bu örnekte basit sabit uzunlukta yer imi kullandığından, bu IRowsetLocate::Hash yöntemi uygulamıyor. Değişken uzunlukta yer imleri veya hesaplama pahalı yer imleri sağlayıcınızı kullanır, IRowsetLocate::Hash yöntemini de uygulamak istediğiniz.)
Tam uygulanması IRowsetLocateImpl Bu gibi görünüyor:
/////////////////////////////////////////////////////////////////////////// RowLoc.h
// class IRowsetLocateImpl
template <class T>
class ATL_NO_VTABLE IRowsetLocateImpl : public IRowsetImpl<T>
{
public:
STDMETHOD (Compare)(HCHAPTER hReserved, ULONG cbBookmark1,
const BYTE * pBookmark1, ULONG cbBookmark2, const BYTE * pBookmark2,
DBCOMPARE * pComparison)
{
ATLTRACE("IRowsetLocateImpl::Compare");
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 (*pBookmark1 == *pBookmark2)
*pComparison = DBCOMPARE_EQ;
if (*pBookmark1 < *pBookmark2)
*pComparison = DBCOMPARE_LT;
if (*pBookmark1 > *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)
{
ATLTRACE("IRowsetLocateImpl::GetRowsAt");
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();
LONG iRowsetTemp = m_iRowset; // Cache the current rowset
m_iRowset = *pBookmark;
if (*pBookmark == DBBMK_FIRST)
m_iRowset = 1;
if (*pBookmark == DBBMK_LAST)
m_iRowset = pT->m_rgRowData.GetSize();
// Call IRowsetImpl::GetNextRows to actually get the rows.
hr = GetNextRows(hReserved2, lRowsOffset,
cRows, pcRowsObtained, prghRows);
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;
ATLTRACE("IRowsetLocateImpl::GetRowsByBookmark");
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 validated row
ULONG ulRowsObtained = 0;
if (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;
else
return hr;
}
STDMETHOD (Hash)(HCHAPTER hReserved, ULONG cBookmarks,
const ULONG rgcbBookmarks[], const BYTE * rgpBookmarks[],
DWORD rgHashedValues[], DBROWSTATUS rgBookmarkStatus[])
{
ATLTRACENOTIMPL("IRowsetLocateImpl::GetRowsByBookmark");
}
// 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 ((*pBookmark <= 0 || *pBookmark > nRows)
&& *pBookmark != DBBMK_FIRST && *pBookmark != DBBMK_LAST)
{
ATLTRACE("Bookmark has invalid range");
return DB_E_BADBOOKMARK;
}
return S_OK;
}
};
Bir sonraki konuda, sen-ecek görmek dinamik olarak tüketiciye döndürülen sütunlar belirleme.