Share via


Deleting Rows

IRowsetChange also enables consumers to delete rows from the rowset. IRowsetChange::DeleteRows deletes rows from the rowset by overwriting the entire row with at signs (@). Deletions made through DeleteRows are applied to the data source immediately. The source code for IRowsetChange::DeleteRows follows; you can find the complete source code for IRowsetChange in RowChg.cpp.

// CImpIRowsetChange::DeleteRows ---------------------------------------
//
// @mfunc Deletes rows from the provider.  If Errors on individual rows
// occur, the DBERRORINFO array is updated to reflect the error and S_FALSE
// is returned instead of S_OK.
//
// @rdesc HRESULT indicating the status of the method
//      @Flag S_OK                  | All row handles deleted
//      @Flag DB_S_ERRORSOCCURRED   | Some, but not all, row handles deleted
//      @Flag E_INVALIDARG          | Arguments did not match spec.
//      @Flag E_OUTOFMEMORY         | Could not allocated error array
//
STDMETHODIMP CImpIRowsetChange::DeleteRows
    (
      HCHAPTER      hChapter,       //@parm IN  | The Chapter handle.
      DBCOUNTITEM     cRows,         //@parm IN   | Number of rows to delete
      const HROW      rghRows[],      //@parm IN   | Array of handles to delete
      DBROWSTATUS      rgRowStatus[]   //@parm OUT | Error information
    )
{
    DBCOUNTITEM   chRow       = 0L;
    DBCOUNTITEM cErrors     = 0L;
    BYTE*      pbProvRow   = NULL;

    // If No Row handle, just return.
    if( cRows == 0 )
        return( S_OK );

    // Check for Invalid Arguments
    if ( !rghRows )
        return( E_INVALIDARG );

    // Process row handles
    while (chRow < cRows)
    {
      if( rgRowStatus )
         rgRowStatus[chRow] = DBROWSTATUS_S_OK;

        // Is row handle valid
        if( (m_pObj->m_prowbitsIBuffer)->IsSlotSet( (ULONG)rghRows[chRow]) != S_OK )
        {
            // Log Error
         if( rgRowStatus )
            rgRowStatus[chRow]= DBROWSTATUS_E_INVALID;

            cErrors++;
            chRow++;
            continue;
      }

        // Get RowBuffer to look at which row this applies to
        pbProvRow = (BYTE *) (m_pObj->GetRowBuff((DBCOUNTITEM) rghRows[chRow], TRUE ));

        // Has row already been deleted
        // S_OK means deleted
        if( m_pObj->m_pFileio->IsDeleted((DBBKMARK) ((PROWBUFF) pbProvRow)->pbBmk ) == S_OK )
        {
         if( rgRowStatus )
            rgRowStatus[chRow] = DBROWSTATUS_E_DELETED;
            cErrors++;
            chRow++;
            continue;
        }

        // Delete the Row,
        if( m_pObj->m_pFileio->DeleteRow((DBBKMARK) ((PROWBUFF) pbProvRow)->pbBmk) != S_OK )
        {
         // Some better decision as to what rowstatus to set could be done here..
         if( rgRowStatus )
            rgRowStatus[chRow] = DBROWSTATUS_E_FAIL;
            cErrors++;
            chRow++;
            continue;
        }

      // Delete worked correctly
      chRow++;

   } //while


   // If everything went OK except errors in rows use DB_S_ERRORSOCCURRED.
   return cErrors ? ( cErrors < cRows ) ? 
      ( DB_S_ERRORSOCCURRED ) : ( DB_E_ERRORSOCCURRED ) : ( S_OK );
}

See Also

Tasks

Writing an OLE DB Provider: An Introduction