⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icrrowsetimpl.h

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 H
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * $Id: ICRRowsetImpl.h,v 1.3 2002/08/28 20:07:45 warmerda Exp $ * * Project:  OpenGIS Simple Features Reference Implementation * Purpose:  RowsetInterface implementation specifically for columns rowset. * Author:   Frank Warmerdam <warmerdam@pobox.com> * * This code is closely derived from the code in ATLDB.H for IRowsetImpl. * It basically modifies the CRowsetImpl to call GetRCDBStatus() on the * derived class from the GetDBStatus() method, allowing a field to be marked * as DBSTATUS_S_ISNULL.  Also, there are some changes to handle null field * status properly. * ****************************************************************************** * Copyright (c) 2001, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: ICRRowsetImpl.h,v $ * Revision 1.3  2002/08/28 20:07:45  warmerda * Get the pSrcData from m_rgRowData[] in GetDBStatus() * * Revision 1.2  2002/08/28 17:42:07  warmerda * changed to unix text format * * Revision 1.1  2002/08/09 21:36:39  warmerda * New * * Revision 1.3  2002/01/31 16:47:41  warmerda * fix up docs a bit * * Revision 1.2  2001/10/15 15:21:07  warmerda * pass raw data points to GetRCDBStatus * */#ifndef _ICRRowsetImpl_INCLUDED#define _ICRRowsetImpl_INCLUDED// ICRRowsetImpltemplate <class T, class RowsetInterface, 		  class RowClass = CSimpleRow, 		  class MapClass = CAtlMap < RowClass::KeyType, RowClass* > >class ATL_NO_VTABLE ICRRowsetImpl : public RowsetInterface{public:	typedef RowClass _HRowClass;	ICRRowsetImpl()	{		m_iRowset = 0;		m_bCanScrollBack = false;		m_bCanFetchBack = false;		m_bRemoveDeleted = true;		m_bIRowsetUpdate = false;		m_bReset = true;		m_bExternalFetch = false;	}	~ICRRowsetImpl()	{		//for (int i = 0; i < m_rgRowHandles.GetCount(); i++)		//	delete (m_rgRowHandles.GetValueAt(i));		POSITION pos = m_rgRowHandles.GetStartPosition();		while( pos != NULL )		{			MapClass::CPair *pPair = m_rgRowHandles.GetNext(pos);			ATLASSERT( pPair != NULL );			delete pPair->m_value;		}	}	HRESULT RefRows(DBCOUNTITEM cRows, const HROW rghRows[], DBREFCOUNT rgRefCounts[],					DBROWSTATUS rgRowStatus[], BOOL bAdd)	{		ATLTRACE(atlTraceDBProvider, 2, _T("ICRRowsetImpl::AddRefRows\n"));		if (cRows == 0)			return S_OK;		if (rghRows == NULL)			return E_INVALIDARG;		T::ObjectLock cab((T*)this);		BOOL bSuccess1 = FALSE;		BOOL bFailed1 = FALSE;		DBROWSTATUS rs;		DWORD dwRef;		__if_exists(T::Fire_OnRowChange)		{			// Maintain an array of handles w/ zero ref counts for notification			CAtlArray<HROW>  arrZeroHandles;		}		for (ULONG iRow = 0; iRow < cRows; iRow++)		{			HROW hRowCur = rghRows[iRow];			RowClass* pRow;			bool bFound = m_rgRowHandles.Lookup((RowClass::KeyType)hRowCur, pRow);			if (!bFound || pRow == NULL)			{				ATLTRACE(atlTraceDBProvider, 0, _T("Could not find HANDLE %x in list\n"));				rs = DBROWSTATUS_E_INVALID;				dwRef = 0;				bFailed1 = TRUE;			}			else			{				if (pRow->m_status != DBPENDINGSTATUS_UNCHANGED &&					pRow->m_status != DBPENDINGSTATUS_INVALIDROW &&					pRow->m_dwRef == 0 && !bAdd)				{					if (rgRefCounts)						rgRefCounts[iRow] = 0;					if (rgRowStatus != NULL)						rgRowStatus[iRow] = DBROWSTATUS_E_INVALID;					bFailed1 = TRUE;					continue;				}				// Check if we're in immediate or deferred mode				CComVariant varDeferred;				bool bDeferred;				T* pT = (T*)this;				HRESULT hr = pT->GetPropValue(&DBPROPSET_ROWSET, 					DBPROP_IRowsetUpdate, &varDeferred);				(FAILED(hr) || varDeferred.boolVal == ATL_VARIANT_FALSE) ? 					bDeferred = false : bDeferred = true;				if (!bDeferred && bAdd &&					pRow->m_status == DBPENDINGSTATUS_DELETED)				{					bFailed1 = TRUE;					if (rgRowStatus != NULL)						rgRowStatus[iRow] = DBROWSTATUS_E_DELETED;					continue;				}				if (bAdd)					dwRef = pRow->AddRefRow();				else				{					dwRef = pRow->ReleaseRow();					if ((pRow->m_status != DBPENDINGSTATUS_UNCHANGED &&						pRow->m_status != 0 &&						pRow->m_status != DBPENDINGSTATUS_INVALIDROW) &&						bDeferred)					{						if (rgRefCounts)							rgRefCounts[iRow] = dwRef;						if (rgRowStatus != NULL)							rgRowStatus[iRow] = DBROWSTATUS_S_PENDINGCHANGES;						bSuccess1 = TRUE;						continue;					}					if (dwRef == 0)					{						__if_exists(T::Fire_OnRowsetChange)						{							_ATLTRY							{								arrZeroHandles.Add(hRowCur);							}							_ATLCATCH( e )							{								_ATLDELETEEXCEPTION( e );								return E_FAIL;							}						}						// Now determine if the DBPROP_REMOVEDELETED property						// is ATL_VARIANT_FALSE.  If so, then do NOT remove the						// row.						hr = pT->GetPropValue(&DBPROPSET_ROWSET, 							DBPROP_REMOVEDELETED, &varDeferred);						if (FAILED(hr) || varDeferred.boolVal != ATL_VARIANT_FALSE)						{							delete pRow;							m_rgRowHandles.RemoveKey((RowClass::KeyType)hRowCur);						}					}				}				bSuccess1 = TRUE;				rs = DBROWSTATUS_S_OK;			}			if (rgRefCounts)				rgRefCounts[iRow] = dwRef;			if (rgRowStatus != NULL)				rgRowStatus[iRow] = rs;		}		__if_exists(T::Fire_OnRowsetChange)		{			if (!bAdd && arrZeroHandles.GetCount() > 0)			{				T* pT = (T*)this;				pT->Fire_OnRowChange(pT, (ULONG_PTR)arrZeroHandles.GetCount(), arrZeroHandles.GetData(), 					DBREASON_ROW_RELEASE, DBEVENTPHASE_DIDEVENT, FALSE); 			}		}		if (!bSuccess1 && !bFailed1)		{			ATLTRACE(atlTraceDBProvider, 0, _T("ICRRowsetImpl::RefRows Unexpected state\n"));			return E_FAIL;		}		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("ICRRowsetImpl::AddRefRows\n"));		if (cRows == 0)			return S_OK;		return RefRows(cRows, rghRows, rgRefCounts, rgRowStatus, TRUE);	}	virtual DBSTATUS GetDBStatus(RowClass* pRow, ATLCOLUMNINFO *poColInfo)	{            T* pT = (T*) this;            void *pSrcData;                        pSrcData = (void*)&(pT->m_rgRowData[pRow->m_iRowset]);            return pT->GetRCDBStatus(pRow, poColInfo, pSrcData);	}	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)	{		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[pRow->m_iRowset]);		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 TransferData<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;	}	HRESULT GetNextRowsSkipDeleted(HCHAPTER /*hReserved*/,									DBROWOFFSET lRowsOffset,									DBROWCOUNT cRows,									DBCOUNTITEM *pcRowsObtained,									HROW **prghRows)	{		ATLTRACE(atlTraceDBProvider, 2, _T("ICRRowsetImpl::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  && !m_bCanFetchBack)			return DB_E_CANTFETCHBACKWARDS;		DBROWOFFSET cRowsInSet = (DBROWOFFSET)pT->m_rgRowData.GetCount();		DBROWOFFSET iStepSize = cRows >= 0 ? 1 : -1;		// If cRows == MINLONG_PTR, we can't use ABS on it.  Therefore, we reset it		// to a value just greater than cRowsInSet		if (cRows == MINLONG_PTR && cRowsInSet != MINLONG_PTR)			cRows = cRowsInSet + 2;	// set the value to something we can deal with		else			cRows = AbsVal(cRows);		// First, simulate the operation, skipping over any deleted rows, calculate the number of rows retrieved,		// and return an error code if appropriate		DBROWOFFSET nCurrentRow = m_iRowset;		// Note, if m_bReset, m_iRowset must be 0		if ( m_bReset && (lRowsOffset < 0 || ( lRowsOffset == 0 && iStepSize < 0 ) ) )			nCurrentRow = cRowsInSet;		// skip the rows according to the lRowsOffset value		if( lRowsOffset > 0 )		{			DBROWOFFSET nRowsToSkip = lRowsOffset;			while( nRowsToSkip > 0 && nCurrentRow <= cRowsInSet )			{				RowClass* pRow = NULL;				RowClass::KeyType key = nCurrentRow + 1;				bool bFound = m_rgRowHandles.Lookup(key,pRow);				if( bFound && pRow != NULL )				{					if( pRow->m_status == DBPENDINGSTATUS_DELETED )					{						nCurrentRow++;						continue;					}				}				nCurrentRow++;				nRowsToSkip--;			}			if( nCurrentRow > cRowsInSet )				return DB_S_ENDOFROWSET;		}		else if( lRowsOffset < 0 )		{			DBROWOFFSET nRowsToSkip = lRowsOffset;			if (nRowsToSkip == MINLONG_PTR && cRowsInSet != MINLONG_PTR)				nRowsToSkip = cRowsInSet + 2;	// set the value to something we can deal with			else				nRowsToSkip = -nRowsToSkip;			while( nRowsToSkip > 0 && nCurrentRow > 0 )			{				nCurrentRow--;				RowClass* pRow = NULL;				RowClass::KeyType key = nCurrentRow + 1;				bool bFound = m_rgRowHandles.Lookup(key,pRow);				if( bFound && pRow != NULL )				{					if( pRow->m_status == DBPENDINGSTATUS_DELETED )					{						continue;					}				}				nRowsToSkip--;			}			if( nCurrentRow < 0 )				return DB_S_ENDOFROWSET;		}		DBROWOFFSET nFetchStartPosition = nCurrentRow;		// now fetch the rows		DBROWOFFSET cRowsToFetch = cRows;		DBROWOFFSET cRowsFetched = 0;		if( iStepSize == 1 )		{			while( cRowsToFetch > 0 && nCurrentRow < cRowsInSet )			{				RowClass* pRow = NULL;				RowClass::KeyType key = nCurrentRow + 1;				bool bFound = m_rgRowHandles.Lookup(key,pRow);				if( bFound && pRow != NULL )				{					if( pRow->m_status == DBPENDINGSTATUS_DELETED )					{						nCurrentRow++;						continue;					}				}				// now we would fetch the row				cRowsFetched++;				cRowsToFetch--;				nCurrentRow++;			}		}		else		{			while( cRowsToFetch > 0 && nCurrentRow > 0 )			{				nCurrentRow--;				RowClass* pRow = NULL;				RowClass::KeyType key = nCurrentRow + 1;				bool bFound = m_rgRowHandles.Lookup(key,pRow);				if( bFound && pRow != NULL )				{					if( pRow->m_status == DBPENDINGSTATUS_DELETED )					{						continue;					}				}				// now we would fetch the row				cRowsFetched++;				cRowsToFetch--;			}		}		//  we could not fetch any rows		if( cRowsFetched == 0 )			return DB_S_ENDOFROWSET;		// Simulation completed... no problems detected... we can now perform the real fetching		// 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); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -