|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998-2000.
//
// File: BmkAcc.cxx
//
// Contents: Distributed Bookmark accessor class
//
// Classes: CDistributedBookmarkAccessor
//
// History: 25-Sep-98 VikasMan Created
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include "bmkacc.hxx"
//+---------------------------------------------------------------------------
//
// Member: CDistributedBookmarkAccessor::CDistributedBookmarkAccessor, public
//
// Synopsis: Builds the bookmark accessors
//
// Arguments: [aCursor] -- Child rowsets.
// [cCursor] -- Count of [aCursor].
// [dwAccessorFlags] -- Binding type.
// [pStatus] -- Status reported here. May be null.
// [iBookmark] -- Ordinal of bookmark column.
// [cbBookmark] -- Size of bookmark.
//
// History: 28-Sep-98 VikasMan Created.
// 06-Jan-2000 KLam Fixed bindings
//
//----------------------------------------------------------------------------
CDistributedBookmarkAccessor::CDistributedBookmarkAccessor( IRowset ** const aCursor, unsigned cCursor, DBACCESSORFLAGS dwAccessorFlags, DBBINDSTATUS* pStatus, DBORDINAL iBookmark, DBBKMARK cbBookmark ) { Win4Assert( aCursor && cCursor > 0 );
DBBINDING bindBmk; DBBINDSTATUS bmkBindStatus; unsigned iChild; SCODE sc = S_OK; SCODE scLast = S_OK;
TRY { _xIacc.Init( cCursor );
for ( iChild = 0; iChild < cCursor; iChild++ ) { sc = aCursor[iChild]->QueryInterface( IID_IAccessor, _xIacc[iChild].GetQIPointer() ); if ( FAILED(sc) ) { scLast = sc; vqDebugOut(( DEB_ERROR, "CDistributedBookmarkAccessor: CreateAccessor(child %d) returned 0x%x\n", iChild, sc )); // Don't throw here. We want to continue on and catch all possible errors
} } if (FAILED(scLast)) { THROW( CException(scLast) ); } // Binding structure for child bookmarks
//----------------------------------//
// Cursor# | Value1 | Value2 | ... // // The first 4 bytes are shared by cursor #
// Status // // and status
//----------------------------------//
_xhaccBookmark.Init( cCursor ); RtlZeroMemory( &bindBmk, sizeof bindBmk ); bindBmk.iOrdinal = iBookmark; bindBmk.wType = DBTYPE_BYTES; bindBmk.dwPart = DBPART_VALUE | DBPART_STATUS; bindBmk.cbMaxLen = ( cbBookmark - sizeof(DBROWSTATUS) ) / cCursor; bindBmk.obValue = sizeof( DBROWSTATUS ); bindBmk.obStatus = 0; for ( iChild = 0 ; iChild < cCursor; iChild++ ) { sc = _xIacc[iChild]->CreateAccessor( dwAccessorFlags, 1, &bindBmk, 0, &(_xhaccBookmark[iChild]), &bmkBindStatus ); if ( FAILED(sc) ) { // remember that at least one child failed to create accessor
scLast = sc; if ( pStatus && S_OK != scLast ) { // set Status to reflect the failure in binding the bookmark column
*pStatus = bmkBindStatus; }
vqDebugOut(( DEB_ERROR, "CDistributedAccessor: CreateAccessor for bookmark(child %d) returned 0x%x\n", iChild, sc )); // Don't throw here. We want to continue on and find all failures
continue; } bindBmk.obValue += bindBmk.cbMaxLen; } if (FAILED(scLast)) { THROW( CException(scLast) ); } } CATCH( CException, e ) { _ReleaseAccessors();
RETHROW(); } END_CATCH
Win4Assert( SUCCEEDED(sc) ); }
//+---------------------------------------------------------------------------
//
// Member: CDistributedBookmarkAccessor::ReleaseAccessors, private
//
// Synopsis: Release all the bookmark accessors
//
// Arguments: none
//
// History: 28-Sep-98 VikasMan Created.
//
//----------------------------------------------------------------------------
void CDistributedBookmarkAccessor::_ReleaseAccessors() { unsigned iChild; for ( iChild = 0; iChild < _xIacc.Count(); iChild++ ) { if ( _xIacc[iChild].GetPointer() && _xhaccBookmark[iChild] ) { _xIacc[iChild]->ReleaseAccessor( _xhaccBookmark[iChild], 0 ); } } }
//+---------------------------------------------------------------------------
//
// Member: CDistributedBookmarkAccessor::GetData, public
//
// Synopsis: Fetches the bookmark data
//
// Arguments: [iChild] -- Index of child cursor from which base data is
// to be fetched. Indicates 'current' row in [ahrow].
// [ahrow] -- 'Top' HROW for all cursors. Used for bookmark
// hints.
// [pBookmarkData] -- Value returned here, starting at offset 0
// [cbBookmark] -- Length of bookmark
// [aCursor] -- Child Rowsets
// [cCursor] -- Count of child cursors
// [pStatus] -- GetData Status returned here, if pStatus is not null
//
// Returns: SCODE
//
// History: 28-Sep-98 VikasMan Created.
//
//----------------------------------------------------------------------------
SCODE CDistributedBookmarkAccessor::GetData( unsigned iChild, HROW * ahrow, void * pBookmarkData, DBBKMARK cbBookmark, IRowset * * const aCursor, ULONG cCursor, SCODE * pStatus ) { SCODE sc = S_OK;
RtlFillMemory( pBookmarkData, cbBookmark, 0xFF );
if ( pStatus ) { *pStatus = DBSTATUS_S_OK; }
for ( unsigned i = 0; i < cCursor; i++ ) { SCODE sc2 = S_OK;
if ( ahrow[i] != (HROW)0xFFFFFFFF ) { sc2 = aCursor[i]->GetData( ahrow[i], GetHAccessor(i), pBookmarkData );
if ( SUCCEEDED(sc2) && pStatus && DBSTATUS_S_OK == *pStatus ) { *pStatus = *( (SCODE*)pBookmarkData ); } }
if ( FAILED(sc2) ) { if ( i == iChild ) { vqDebugOut(( DEB_ERROR, "CDistributedBookmarkAccessor::GetData: Child GetData returned 0x%x\n", sc )); sc = sc2; break; } else { // This can fail as we can have a invalid row handle for hints
vqDebugOut(( DEB_TRACE, "CDistributedBookmarkAccessor::GetData: Child GetData returned 0x%x\n", sc )); continue; } } }
*(ULONG UNALIGNED *)(pBookmarkData) = iChild;
return sc; }
|