📄 ifrowsetimpl.h
字号:
} HRESULT hr = S_OK; if (bSuccess1 && bFailed1) hr = DB_S_ERRORSOCCURRED; if (!bSuccess1 && bFailed1) hr = DB_E_ERRORSOCCURRED; return hr; } STDMETHOD(AddRefRows)(DBCOUNTITEM cRows, const HROW rghRows[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[]) { ATLTRACE(atlTraceDBProvider, 2, _T("IFRowsetImpl::AddRefRows\n")); if (cRows == 0) return S_OK; return RefRows(cRows, rghRows, rgRefCounts, rgRowStatus, TRUE); } virtual DBSTATUS GetDBStatus(RowClass* , ATLCOLUMNINFO*) { return DBSTATUS_S_OK; } virtual HRESULT SetDBStatus(DBSTATUS*, RowClass* , ATLCOLUMNINFO*) { // The provider overrides this function to handle special processing // for DBSTATUS_S_ISNULL and DBSTATUS_S_DEFAULT. return S_OK; } OUT_OF_LINE HRESULT GetDataHelper(HACCESSOR hAccessor, ATLCOLUMNINFO*& rpInfo, void** ppBinding, void*& rpSrcData, DBORDINAL& rcCols, CComPtr<IDataConvert>& rspConvert, RowClass* pRow) { HRESULT hr = S_OK; ATLASSERT(ppBinding != NULL); T* pT = (T*) this;// *ppBinding = (void*)pT->m_rgBindings.Lookup((INT_PTR)hAccessor); T::_BindingVector::CPair* pPair = pT->m_rgBindings.Lookup( hAccessor ); if (pPair == NULL || pPair->m_value == NULL) return DB_E_BADACCESSORHANDLE; *ppBinding = pPair->m_value; rpSrcData = (void*)pT->m_rgRowData.GetRow(pRow->m_iRowset, hr); if( rpSrcData == NULL ) return hr; rpInfo = T::GetColumnInfo((T*)this, &rcCols); rspConvert = pT->m_spConvert; return S_OK; } STDMETHOD(GetData)(HROW hRow, HACCESSOR hAccessor, void *pDstData) { T* pT = (T*)this; RowClass* pRow; if (hRow == NULL ) return DB_E_BADROWHANDLE; if( !pT->m_rgRowHandles.Lookup((INT_PTR)hRow, pRow)) return DB_E_BADROWHANDLE; if (pRow == NULL) return DB_E_BADROWHANDLE; return SFTransferData<T, RowClass, MapClass> (pT, true, pDstData, pRow, &(pT->m_rgRowHandles), hAccessor); } HRESULT CreateRow(DBROWOFFSET lRowsOffset, DBCOUNTITEM& cRowsObtained, HROW* rgRows) { RowClass* pRow = NULL; ATLASSERT(lRowsOffset >= 0); RowClass::KeyType key = lRowsOffset+1; ATLASSERT(key > 0); bool bFound = m_rgRowHandles.Lookup(key,pRow); if (!bFound || pRow == NULL) { ATLTRY(pRow = new RowClass(lRowsOffset)) if (pRow == NULL) return E_OUTOFMEMORY; _ATLTRY { m_rgRowHandles.SetAt(key, pRow); } _ATLCATCH( e ) { _ATLDELETEEXCEPTION( e ); delete pRow; pRow = NULL; return E_OUTOFMEMORY; } } pRow->AddRefRow(); m_bReset = false; rgRows[cRowsObtained++] = (HROW)key; return S_OK; } STDMETHOD(GetNextRows)(HCHAPTER hReserved, DBROWOFFSET lRowsOffset, DBROWCOUNT cRows, DBCOUNTITEM *pcRowsObtained, HROW **prghRows) { DBROWOFFSET lTmpRows = lRowsOffset; ATLTRACE(atlTraceDBProvider, 2, _T("IFRowsetImpl::GetNextRows\n")); T* pT = (T*) this; __if_exists(T::Fire_OnRowChange) { // Check to see if someone is in an event handler. If we do, then // we should return DB_E_NOTREENTRANT. if (!pT->IncrementMutex()) { // Note, we can't set this above this block because we may // inadvertantly reset somebody else's pcRowsObtained if (pcRowsObtained != NULL) *pcRowsObtained = 0; return DB_E_NOTREENTRANT; } else pT->DecrementMutex(); } if (pcRowsObtained != NULL) *pcRowsObtained = 0; if (prghRows == NULL || pcRowsObtained == NULL) return E_INVALIDARG; if (cRows == 0) return S_OK; HRESULT hr = S_OK; T::ObjectLock cab(pT); if (lRowsOffset < 0 && !m_bCanScrollBack) return DB_E_CANTSCROLLBACKWARDS; if (cRows < 0 ) return DB_E_CANTFETCHBACKWARDS; // Calculate # of rows in set and the base fetch position. If the rowset // is at its head position, then lRowOffset < 0 means moving from the BACK // of the rowset and not the front. if( lRowsOffset == MINLONG_PTR ) return DB_S_ENDOFROWSET; // In the case where the user is moving backwards after moving forwards, // we do not wrap around to the end of the rowset. if ((m_iRowset == 0 && !m_bReset && cRows < 0) ) return DB_S_ENDOFROWSET; // Fire events for OKTODO and ABOUTTODO after all validation has taken // place but before any permanent changes to the rowset state take place __if_exists(T::Fire_OnRowsetChange) { // Only fire these events if we're not being called by a bookmark // operation (which is why m_bExternalFetch would be set to true) if(!m_bExternalFetch) { HRESULT hrNotify = pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_OKTODO, FALSE); if (hrNotify == S_FALSE) return DB_E_CANCELED; else { hrNotify = pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_ABOUTTODO, FALSE); if (hrNotify == S_FALSE) return DB_E_CANCELED; else { hrNotify = pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_SYNCHAFTER, FALSE); if (hrNotify == S_FALSE) return DB_E_CANCELED; } } } } // Note, if m_bReset, m_iRowset must be 0 if (lRowsOffset < 0 && m_bReset) { CPLDebug( "OGR_ATL", "Backup not supported."); return DB_E_CANTFETCHBACKWARDS; } int iStepSize = cRows >= 0 ? 1 : -1; cRows = AbsVal(cRows); lRowsOffset += m_iRowset; *pcRowsObtained = 0; CComHeapPtr<HROW> rghRowsAllocated; if (*prghRows == NULL) { DBROWOFFSET cHandlesToAlloc = cRows; if (iStepSize == -1 && lRowsOffset < cHandlesToAlloc) cHandlesToAlloc = lRowsOffset; rghRowsAllocated.Allocate(cHandlesToAlloc); if(rghRowsAllocated == NULL) return E_OUTOFMEMORY; *prghRows = rghRowsAllocated; } // Check to see if we have the desired number of rows available // from the data source. int cAvailableRows; cAvailableRows = pT->m_rgRowData.CheckRows(lRowsOffset, cRows); if( cAvailableRows < cRows ) { cRows = cAvailableRows; hr = DB_S_ENDOFROWSET; } while (lRowsOffset >= 0 && cRows != 0) { // cRows > cRowsInSet && iStepSize < 0 if (lRowsOffset == 0 && cRows > 0 && iStepSize < 0) break; // in the case where we have iStepSize < 0, move the row back // further because we want the previous row DBROWOFFSET lRow = lRowsOffset; if (iStepSize < 0) lRow += iStepSize; hr = pT->CreateRow(lRow, *pcRowsObtained, *prghRows); if (FAILED(hr)) { RefRows(*pcRowsObtained, *prghRows, NULL, NULL, FALSE); for (ULONG iRowDel = 0; iRowDel < *pcRowsObtained; iRowDel++) *prghRows[iRowDel] = NULL; *pcRowsObtained = 0; return hr; } __if_exists(T::Fire_OnRowsetChange) { if (!m_bExternalFetch) pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_DIDEVENT, TRUE); } cRows--; lRowsOffset += iStepSize; } // If we have multiple rows fetched, return one event, per the specification // containing all rows activated. if (*pcRowsObtained >= 1) { __if_exists(T::Fire_OnRowsetChange) { CAtlArray<HROW> rgActivated; for (size_t ulActivated = 0; ulActivated < *pcRowsObtained; ulActivated++) { // This is a bit of an assumption that all newly activated // rows would have the ref count as 1. Another way to solve this // problem would be to modify the signature of CreateRow to take // a CAtlArray<HROW> as a parameter and store the activated rows. RowClass* pActiveRow; if( m_rgRowHandles.Lookup((*prghRows)[ulActivated], pActiveRow ) && (pActiveRow != NULL && pActiveRow->m_dwRef == 1) ) { _ATLTRY { rgActivated.Add((*prghRows)[ulActivated]); } _ATLCATCH( e ) { _ATLDELETEEXCEPTION( e ); return E_OUTOFMEMORY; } } } if (rgActivated.GetCount() > 0) { pT->Fire_OnRowChange(pT, (DBCOUNTITEM)rgActivated.GetCount(), rgActivated.GetData(), DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, FALSE); } } } if ((lRowsOffset < 0 && cRows) || (lRowsOffset == 0 && cRows > 0 && iStepSize < 0)) hr = DB_S_ENDOFROWSET; m_iRowset = lRowsOffset; if (SUCCEEDED(hr)) rghRowsAllocated.Detach(); return hr; } STDMETHOD(ReleaseRows)(DBCOUNTITEM cRows, const HROW rghRows[], DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[]) { ATLTRACE(atlTraceDBProvider, 2, _T("IFRowsetImpl::ReleaseRows\n")); __if_exists(T::Fire_OnRowChange) { T* pT = (T*) this; // Check to see if someone is in an event handler. If we do, then // we should return DB_E_NOTREENTRANT. if (!pT->IncrementMutex()) return DB_E_NOTREENTRANT; else pT->DecrementMutex(); } if (cRows == 0) return S_OK; rgRowOptions; return RefRows(cRows, rghRows, rgRefCounts, rgRowStatus, FALSE); } STDMETHOD(RestartPosition)(HCHAPTER /*hReserved*/) { ATLTRACE(atlTraceDBProvider, 2, _T("IFRowsetImpl::RestartPosition\n")); T* pT = (T*) this; __if_exists(T::Fire_OnRowsetChange) { // Check to see if someone is in an event handler. If we do, then // we should return DB_E_NOTREENTRANT. if (!pT->IncrementMutex()) return DB_E_NOTREENTRANT; else pT->DecrementMutex(); bool bNeedEvents = ((m_iRowset != 0 || !m_bReset)) ? true : false; // Only fire the events iff. we are actually causing a reset if (bNeedEvents) { HRESULT hrNotify = pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_OKTODO, FALSE); if (hrNotify == S_FALSE) return DB_E_CANCELED; else { hrNotify = pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_ABOUTTODO, FALSE); if (hrNotify == S_FALSE) return DB_E_CANCELED; else { hrNotify = pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_SYNCHAFTER, FALSE); if (hrNotify == S_FALSE) return DB_E_CANCELED; } } } } // Check to see if DBPROP_CANHOLDROWS is set to false. In this case, // return a DB_E_ROWSNOTRELEASED. CComVariant varHoldRows; HRESULT hr = pT->GetPropValue(&DBPROPSET_ROWSET, DBPROP_CANHOLDROWS, &varHoldRows); if (FAILED(hr) || varHoldRows.boolVal == ATL_VARIANT_FALSE) { if (m_rgRowHandles.GetCount() > 0) { RowClass* pRow = NULL; POSITION pos = pT->m_rgRowHandles.GetStartPosition(); while (pos != NULL) { MapClass::CPair* pPair = pT->m_rgRowHandles.GetNext(pos); ATLASSERT( pPair != NULL ); HROW hRow = pPair->m_key; bool bFound = pT->m_rgRowHandles.Lookup(hRow, pRow); if (bFound && pRow != NULL && pRow->m_status != DBPENDINGSTATUS_UNCHANGED) { __if_exists(T::Fire_OnRowsetChange) { if (bNeedEvents) { pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_FAILEDTODO, TRUE); } } return DB_E_ROWSNOTRELEASED; } } } } m_iRowset = 0; m_bReset = true; __if_exists(T::Fire_OnRowsetChange) { // listener must comply so blow off ret val. if (bNeedEvents) pT->Fire_OnRowsetChange(pT, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_DIDEVENT, TRUE); } return S_OK; } MapClass m_rgRowHandles; DBROWOFFSET m_iRowset; // cursor unsigned m_bCanScrollBack:1; unsigned m_bCanFetchBack:1; unsigned m_bRemoveDeleted:1; // DBPROP_REMOVEDELETED unsigned m_bIRowsetUpdate:1; // DBPROP_IRowsetUpdate unsigned m_bReset:1; unsigned m_bExternalFetch:1;};#endif // ifndef _IFRowsetImpl_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -