home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Basic / Visual Basic.60 / COMMON / TOOLS / VCM / VCM.MDB / VcmComponentContainer / 08_Cabinet / ROWLOC.H < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-18  |  5.7 KB  |  194 lines

  1. ///////////////////////////////////////////////////////////////////////////
  2. // ROWLOC.H -- Declarations and implementations for IRowsetLocateImpl
  3. //
  4. // This is a part of the ActiveX Template Library.
  5. // Copyright (C) 1998 Microsoft Corporation
  6. // All rights reserved.
  7. //
  8. // This source code is only intended as a supplement to the
  9. // ActiveX Template Library Reference and related
  10. // electronic documentation provided with the library.
  11. // See these sources for detailed information regarding the
  12. // ActiveX Template Library product.
  13.  
  14. #include "stdafx.h"
  15.  
  16.  
  17. ///////////////////////////////////////////////////////////////////////////
  18. // class IRowsetLocateImpl
  19.  
  20. template <class T>
  21. class ATL_NO_VTABLE IRowsetLocateImpl : public IRowsetImpl<T, IRowsetLocate>
  22. {
  23. public:
  24.     STDMETHOD (Compare)(HCHAPTER hReserved, ULONG cbBookmark1,
  25.         const BYTE * pBookmark1, ULONG cbBookmark2, const BYTE * pBookmark2,
  26.         DBCOMPARE * pComparison)
  27.     {
  28.         ATLTRACE("IRowsetLocateImpl::Compare");
  29.  
  30.         HRESULT hr = ValidateBookmark(cbBookmark1, pBookmark1);
  31.         if (hr != S_OK)
  32.             return hr;
  33.  
  34.         hr = ValidateBookmark(cbBookmark2, pBookmark2);
  35.         if (hr != S_OK)
  36.             return hr;
  37.  
  38.         // Return the value based on the bookmark values
  39.         if (*pBookmark1 == *pBookmark2)
  40.             *pComparison = DBCOMPARE_EQ;
  41.  
  42.         if (*pBookmark1 < *pBookmark2)
  43.             *pComparison = DBCOMPARE_LT;
  44.  
  45.         if (*pBookmark1 > *pBookmark2)
  46.             *pComparison = DBCOMPARE_GT;
  47.  
  48.         return S_OK;
  49.     }
  50.  
  51.     STDMETHOD (GetRowsAt)(HWATCHREGION hReserved1, HCHAPTER hReserved2,
  52.         ULONG cbBookmark, const BYTE * pBookmark, LONG lRowsOffset,
  53.         LONG cRows, ULONG * pcRowsObtained, HROW ** prghRows)
  54.     {
  55.         ATLTRACE("IRowsetLocateImpl::GetRowsAt");
  56.         T* pT = (T*)this;
  57.  
  58.         // Check bookmark
  59.         HRESULT hr = ValidateBookmark(cbBookmark, pBookmark);
  60.         if (hr != S_OK)
  61.             return hr;
  62.  
  63.         // Check the other pointers
  64.         if (pcRowsObtained == NULL || prghRows == NULL)
  65.             return E_INVALIDARG;
  66.  
  67.         // Set the current row position to the bookmark.  Handle any
  68.         // normal values
  69.         pT->Lock();
  70.  
  71.         // We need to handle the offset as the start position is defined
  72.         // as the bookmark + offset.  If the offset is negative, and we
  73.         // do not have m_bCanScrollBack then return an error.  The
  74.         // GetNextRows function handles the case where cRows is negative
  75.         // and we don't have m_bCanFetchBack set.
  76.         if (lRowsOffset < 0 && !pT->m_bCanScrollBack)
  77.             return DB_E_CANTSCROLLBACKWARDS;
  78.  
  79.         LONG iRowsetTemp = pT->m_iRowset;  // Cache the current rowset
  80.         pT->m_iRowset = *pBookmark;
  81.         if ((cbBookmark == 1) && (*pBookmark == DBBMK_FIRST))
  82.             pT->m_iRowset = 1;
  83.  
  84.         if ((cbBookmark == 1) && (*pBookmark == DBBMK_LAST))
  85.             pT->m_iRowset = pT->m_rgRowData.GetSize() + 1;
  86.  
  87.         // Set the start position to m_iRowset + lRowsOffset
  88.         pT->m_iRowset += lRowsOffset;
  89.         if (lRowsOffset >= 0)
  90.             (cRows >= 0) ? pT->m_iRowset -= 1 : pT->m_iRowset +=0;
  91.         else
  92.             (cRows >= 0) ? pT->m_iRowset -= 1 : pT->m_iRowset +=0;
  93. //      (lRowsOffset >= 0) ? m_iRowset -= 1 : m_iRowset += 1;
  94.         if (pT->m_iRowset < 0 || pT->m_iRowset > (DWORD)pT->m_rgRowData.GetSize())
  95.         {
  96.             pT->m_iRowset = iRowsetTemp;
  97.             return DB_E_BADSTARTPOSITION;
  98.         }
  99.  
  100.         // Call IRowsetImpl::GetNextRows to actually get the rows.
  101.         hr = pT->GetNextRows(hReserved2, 0, cRows, pcRowsObtained, prghRows);
  102.         pT->m_iRowset = iRowsetTemp;
  103.         pT->Unlock();
  104.         return hr;
  105.     }
  106.  
  107.     STDMETHOD (GetRowsByBookmark)(HCHAPTER hReserved, ULONG cRows,
  108.         const ULONG rgcbBookmarks[], const BYTE * rgpBookmarks[],
  109.         HROW rghRows[], DBROWSTATUS rgRowStatus[])
  110.     {
  111.         HRESULT hr = S_OK;
  112.         ATLTRACE("IRowsetLocateImpl::GetRowsByBookmark");
  113.  
  114.         T* pT = (T*)this;
  115.         if (rgcbBookmarks == NULL || rgpBookmarks == NULL || rghRows == NULL)
  116.             return E_INVALIDARG;
  117.  
  118.         if (cRows == 0)
  119.             return S_OK;    // No rows fetched in this case.
  120.  
  121.         bool bErrors = false;
  122.         pT->Lock();
  123.         for (ULONG l=0; l<cRows; l++)
  124.         {
  125.             // Validate each bookmark before fetching the row.  Note, it is
  126.             // an error for the bookmark to be one of the standard values
  127.             hr = ValidateBookmark(rgcbBookmarks[l], rgpBookmarks[l]);
  128.             if (hr != S_OK)
  129.             {
  130.                 bErrors = TRUE;
  131.                 if (rgRowStatus != NULL)
  132.                 {
  133.                     rgRowStatus[l] = DBROWSTATUS_E_INVALID;
  134.                     continue;
  135.                 }
  136.             }
  137.  
  138.             // Fetch the row, we now that it is a valid row after validation.
  139.             ULONG ulRowsObtained = 0;
  140.             if (pT->CreateRow((long)*rgpBookmarks[l], ulRowsObtained, &rghRows[l]) != S_OK)
  141.             {
  142.                 bErrors = TRUE;
  143.             }
  144.             else
  145.             {
  146.                 if (rgRowStatus != NULL)
  147.                     rgRowStatus[l] = DBROWSTATUS_S_OK;
  148.             }
  149.         }
  150.  
  151.         pT->Unlock();
  152.         if (bErrors)
  153.             return DB_S_ERRORSOCCURRED;
  154.         else
  155.             return hr;
  156.     }
  157.  
  158.     STDMETHOD (Hash)(HCHAPTER hReserved, ULONG cBookmarks,
  159.         const ULONG rgcbBookmarks[], const BYTE * rgpBookmarks[],
  160.         DWORD rgHashedValues[], DBROWSTATUS rgBookmarkStatus[])
  161.     {
  162.         ATLTRACENOTIMPL("IRowsetLocateImpl::GetRowsByBookmark");
  163.     }
  164.  
  165.     // Implementation
  166.     protected:
  167.     HRESULT ValidateBookmark(ULONG cbBookmark, const BYTE* pBookmark)
  168.     {
  169.         T* pT = (T*)this;
  170.         if (cbBookmark == 0 || pBookmark == NULL)
  171.             return E_INVALIDARG;
  172.  
  173.         // All of our bookmarks are DWORDs, if they are anything other than
  174.         // sizeof(DWORD) then we have an invalid bookmark
  175.         if ((cbBookmark != sizeof(DWORD)) && (cbBookmark != 1))
  176.         {
  177.             ATLTRACE("Bookmarks are invalid length, should be DWORDs");
  178.             return DB_E_BADBOOKMARK;
  179.         }
  180.  
  181.         // If the contents of our bookmarks are less than 0 or greater than
  182.         // rowcount, then they are invalid
  183.         UINT nRows = pT->m_rgRowData.GetSize();
  184.         if ((*pBookmark <= 0 || *pBookmark > nRows)
  185.             && *pBookmark != DBBMK_FIRST && *pBookmark != DBBMK_LAST)
  186.         {
  187.             ATLTRACE("Bookmark has invalid range");
  188.             return DB_E_BADBOOKMARK;
  189.         }
  190.  
  191.         return S_OK;
  192.     }
  193. };
  194.