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 );
}

See Also

Tasks

Writing an OLE DB Provider: An Introduction