windows-nt/Source/XPSP1/NT/inetsrv/query/distrib/bmkacc.cxx
2020-09-26 16:20:57 +08:00

237 lines
7.7 KiB
C++

//+---------------------------------------------------------------------------
//
// 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;
}