Managing Rowsets
IRowset provides methods for fetching rows sequentially, exposing data from those rows to consumers, and managing the rows in the rowset. IRowset contains five methods: AddRefRows, GetNextRows, GetData, ReleaseRows, and RestartPosition. The source code for IRowset::AddRefRows follows; you can find the complete source code for the IRowset interface in IRowset.cpp.
Incrementing the Reference Count on Row Handles
AddRefRows increments the reference count on the row handles supplied by the caller. AddRefRows enables consumers to make multiple references to a row in the data cache.
// CImpIRowset::AddRefRows --------------------------------------------------
//
// @mfunc Adds a reference count to an existing row handle
//
// @rdesc Returns one of the following values:
// @flag S_OK | success
// @flag DB_S_ERRORSOCCURRED | some elements of rghRows were invalid
// @flag DB_E_ERRORSOCCURRED | all elements of rghRows were invalid
// @flag E_INVALIDARG | rghRows was a NULL pointer and crow > 0
STDMETHODIMP CImpIRowset::AddRefRows
(
DBCOUNTITEM cRows, // @parm IN | Number of rows to refcount
const HROW rghRows[], // @parm IN | Array of row handles to refcount
DBREFCOUNT rgRefCounts[], // @parm OUT | Array of refcounts
DBROWSTATUS rgRowStatus[] // @parm OUT | Array of row status
)
{
HRESULT hr = S_OK;
DBCOUNTITEM chRow = 0L;
DBCOUNTITEM cErrors = 0L;
ROWBUFF *pRowBuff = NULL;
// check params
if ( cRows && !rghRows )
return ResultFromScode( E_INVALIDARG );
// for each of the HROWs the caller provided...
for (chRow = 0; chRow < cRows; chRow++)
{
// check the row handle
if( ((m_pObj->m_prowbitsIBuffer)->IsSlotSet((ULONG) rghRows[chRow]) == S_OK) &&
(pRowBuff=m_pObj->GetRowBuff((DBCOUNTITEM) rghRows[chRow], TRUE )) &&
(m_pObj->m_pFileio->IsDeleted((DBBKMARK) pRowBuff->pbBmk) != S_OK) )
{
// bump refcount
pRowBuff = m_pObj->GetRowBuff((DBCOUNTITEM) rghRows[chRow], TRUE );
assert( pRowBuff->ulRefCount != 0 );
assert( m_pObj->m_ulRowRefCount != 0 );
++pRowBuff->ulRefCount;
++m_pObj->m_ulRowRefCount;
// stuff new refcount into caller's array
if ( rgRefCounts )
rgRefCounts[chRow] = pRowBuff->ulRefCount;
if ( rgRowStatus )
rgRowStatus[chRow] = DBROWSTATUS_S_OK;
}
else
{
if ( rgRefCounts )
rgRefCounts[chRow] = 0;
if ( rgRowStatus )
{
if ( pRowBuff && m_pObj->m_pFileio->IsDeleted((DBBKMARK) pRowBuff->pbBmk) == S_OK )
rgRowStatus[chRow] = DBROWSTATUS_E_DELETED;
else
rgRowStatus[chRow] = DBROWSTATUS_E_INVALID;
}
++ cErrors;
}
}
// If everything went OK except errors in rows use DB_S_ERRORSOCCURRED.
return cErrors ? ( cErrors < cRows ) ?
ResultFromScode( DB_S_ERRORSOCCURRED ) :
ResultFromScode( DB_E_ERRORSOCCURRED ) :
ResultFromScode( S_OK );
}