IRowsetLocateImpl uygulanması Tamamlanıyor

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:

  1. Geçerli yer işareti işaretçi olduğunu kontrol etmek için ValidateBookmark çağrı.

  2. dword büyüklüğü, ya da bir bayt olduğundan emin olmak için yer işareti boyutunu denetleyin. (Kullanıcı kayıt, CAgentMan , dwBookmark girişinin dwordolmasını belirtir. Tek bayt uzunluğu için özel yer DBMRK_FIRST ve dbmrk_lastkullanılır.)

  3. Dizin dizideki ( DBMRK_FIRST ve dbmrk_lastarasında) geçerli bir konum işaret eden onay.

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.

Index