ROWLOC.H
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:6k
源码类别:

Windows编程

开发平台:

Visual C++

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