windows-nt/Source/XPSP1/NT/inetsrv/query/h/rowseek.hxx
2020-09-26 16:20:57 +08:00

401 lines
12 KiB
C++

//+---------------------------------------------------------------------------
//
// Copyright (C) 1995-1995, Microsoft Corporation.
//
// File: rowseek.hxx
//
// Contents: Declarations of classes for row seek descriptions,
// used with the IRowset implementations.
//
// Classes: CRowSeekDescription - base class
// CRowSeekNext - for GetNextRows
// CRowSeekAt - for GetRowsAt
// CRowSeekAtRatio - for GetRowsAtRatio
// CRowSeekByBookmark - for GetRowsByBookmark
// CRowSeekByValues - for GetRowsByValues (maybe someday)
//
// History: 03 Apr 1995 AlanW Created
//
//----------------------------------------------------------------------------
#pragma once
#include <bigtable.hxx>
//+-------------------------------------------------------------------------
//
// Class: CRowSeekDescription
//
// Purpose: Describes row positioning operation for a GetRows call
//
// Notes: This is a base class for one of several derived classes
// that give row positioning parameters for various types of
// GetRows operations.
//
//--------------------------------------------------------------------------
enum RowSeekMethod
{
eRowSeekNull = 0,
eRowSeekCurrent = 1,
eRowSeekAt = 2,
eRowSeekAtRatio = 3,
eRowSeekByBookmark = 4,
};
class CRowSeekDescription
{
public:
CRowSeekDescription( DWORD eType, CI_TBL_CHAPT chapt )
: _chapt( chapt )
{ }
virtual ~CRowSeekDescription( ) { }
virtual void Marshall( PSerStream & stm ) const = 0;
virtual unsigned MarshalledSize( void ) const;
virtual BOOL IsCurrentRowSeek(void) const { return FALSE; }
virtual BOOL IsByBmkRowSeek(void) const { return FALSE; }
virtual SCODE GetRows(
CTableCursor & rCursor,
CTableSource & rTable,
CGetRowsParams& rFetchParams,
XPtr<CRowSeekDescription>& pSeekDescOut) const = 0;
virtual void MergeResults( CRowSeekDescription * pRowSeek );
virtual BOOL IsDone(void) const
{
return FALSE;
}
CI_TBL_CHAPT GetChapter() const { return _chapt; }
protected:
void MarshallBase( PSerStream & stm, DWORD eType ) const;
void SetChapter(CI_TBL_CHAPT Chapter)
{
_chapt = Chapter;
}
private:
CI_TBL_CHAPT _chapt;
};
//+-------------------------------------------------------------------------
//
// Class: CRowSeekNext
//
// Purpose: Describes row positioning operation for a GetNextRows call.
// The only parameter is the number of rows to be skipped prior
// to the transfer operation.
//
//--------------------------------------------------------------------------
class CRowSeekNext: public CRowSeekDescription
{
public:
CRowSeekNext( CI_TBL_CHAPT chapt,
LONG cRowsToSkip )
: CRowSeekDescription( eRowSeekCurrent, chapt )
{
SetSkip( cRowsToSkip );
}
CRowSeekNext( PDeSerStream & stm, int iVersion );
BOOL IsCurrentRowSeek(void) const
{
return TRUE;
}
void Marshall( PSerStream & stm ) const;
SCODE GetRows( CTableCursor & rCursor,
CTableSource & rTable,
CGetRowsParams& rFetchParams,
XPtr<CRowSeekDescription>& pSeekDescOut) const;
LONG GetSkip() const
{
return _cSkip;
}
void SetSkip(LONG cRowsToSkip)
{
_cSkip = cRowsToSkip;
}
private:
LONG _cSkip; // rows to skip
};
//+-------------------------------------------------------------------------
//
// Class: CRowSeekAt
//
// Purpose: Describes row positioning operation for a GetRowsAt call.
// The parameters are the bookmark for the desired position,
// and the offset from that position.
//
//--------------------------------------------------------------------------
class CRowSeekAt: public CRowSeekDescription
{
public:
CRowSeekAt( HWATCHREGION hRegion,
CI_TBL_CHAPT chapt,
LONG lRowOffset,
CI_TBL_BMK bmk )
: CRowSeekDescription( eRowSeekAt, chapt ),
_hRegion (hRegion),
_cRowsOffset ( lRowOffset ),
_bmkOffset ( bmk )
{ }
CRowSeekAt( PDeSerStream & stm, int iVersion );
void Marshall( PSerStream & stm ) const;
SCODE GetRows( CTableCursor & rCursor,
CTableSource & rTable,
CGetRowsParams& rFetchParams,
XPtr<CRowSeekDescription>& pSeekDescOut) const;
WORKID Bmk() const {
return (WORKID)_bmkOffset;
}
LONG Offset() const {
return _cRowsOffset;
}
private:
HWATCHREGION _hRegion;
LONG _cRowsOffset;
CI_TBL_BMK _bmkOffset;
};
//+-------------------------------------------------------------------------
//
// Class: CRowSeekAtRatio
//
// Purpose: Describes row positioning operation for a GetRowsAtRatio
// call. The parameters are the numerator and denominator
// of the ratio. If this operation is restarted, the class
// is transformed into a CRowSeekAt for the restart wid
// and a skip of one.
//
//--------------------------------------------------------------------------
class CRowSeekAtRatio: public CRowSeekDescription
{
public:
CRowSeekAtRatio( HWATCHREGION hRegion,
CI_TBL_CHAPT chapt,
ULONG ulNum,
ULONG ulDen )
: CRowSeekDescription( eRowSeekAtRatio, chapt ),
_hRegion (hRegion),
_ulNumerator( ulNum ),
_ulDenominator( ulDen )
{ }
CRowSeekAtRatio( PDeSerStream & stm, int iVersion );
void Marshall( PSerStream & stm ) const;
SCODE GetRows( CTableCursor & rCursor,
CTableSource & rTable,
CGetRowsParams& rFetchParams,
XPtr<CRowSeekDescription>& pSeekDescOut) const;
ULONG RatioNumerator() const
{
return _ulNumerator;
}
ULONG RatioDenominator() const
{
return _ulDenominator;
}
private:
HWATCHREGION _hRegion;
ULONG _ulNumerator;
ULONG _ulDenominator;
};
//+-------------------------------------------------------------------------
//
// Class: CRowSeekByBookmark
//
// Purpose: Describes row positioning operation for a GetRowsByBookmark
// call. The parameter is an array of bookmarks.
// This class also contains an array of SCODEs to record
// the status of bookmark lookups.
//
//--------------------------------------------------------------------------
class CRowSeekByBookmark: public CRowSeekDescription
{
public:
//
// NOTE: For this constructor, the CRowSeekDescription will now
// own the memory pointed to by pBookmarks.
CRowSeekByBookmark( CI_TBL_CHAPT chapt,
ULONG cBookmarks,
CI_TBL_BMK * pBookmarks = 0 )
: CRowSeekDescription( eRowSeekByBookmark, chapt ),
_cBookmarks ( cBookmarks ),
_maxRet ( cBookmarks ),
_aBookmarks ( pBookmarks ),
_cValidRet ( 0 ),
_ascRet ( 0 )
{
if (0 == pBookmarks)
_cBookmarks = 0;
}
CRowSeekByBookmark( PDeSerStream & stm, int iVersion );
virtual ~CRowSeekByBookmark( );
virtual BOOL IsByBmkRowSeek(void) const { return TRUE; }
void Marshall( PSerStream & stm ) const;
SCODE GetRows( CTableCursor & rCursor,
CTableSource & rTable,
CGetRowsParams& rFetchParams,
XPtr<CRowSeekDescription>& pSeekDescOut) const;
void MergeResults( CRowSeekDescription * pRowSeek );
BOOL IsDone(void) const
{
return _cBookmarks == 0;
}
ULONG GetValidStatuses(void) { return _cValidRet; }
SCODE GetStatus(unsigned i) { return _ascRet[i]; }
private:
void _SetStatus( unsigned i, SCODE sc);
ULONG _cBookmarks; // size of _aBookmarks
ULONG _maxRet; // size of _ascRet
ULONG _cValidRet; // number of valid entries in _ascRet
CI_TBL_BMK* _aBookmarks; // array of bookmarks
SCODE* _ascRet; // array of returned statuses
};
//+-------------------------------------------------------------------------
//
// Function: MarshallRowSeekDescription, public inline
//
// Synopsis: Marshall a row seek description and assign to a smart
// pointer.
//
// Arguments: [stmSer] - Deserialization stream
// [iVersion] - output stream version
// [pRowSeek] - pointer to row seek description
//
// Returns: Nothing. Throws if error.
//
// History: 02 May 1995 AlanW Created
//
//+-------------------------------------------------------------------------
inline void MarshallRowSeekDescription(
PSerStream &stmSer,
int iVersion,
CRowSeekDescription* pRowSeek)
{
if (0 == pRowSeek)
{
stmSer.PutULong(eRowSeekNull);
}
else
{
pRowSeek->Marshall(stmSer);
}
}
//+-------------------------------------------------------------------------
//
// Function: UnmarshallRowSeekDescription, public inline
//
// Synopsis: Unmarshall a row seek description and assign to a smart
// pointer.
//
// Arguments: [stmDeser] - Deserialization stream
// [iVersion] - input stream version
// [xpRowSeek] - smart pointer to row seek description
//
// Returns: Nothing. Throws if error.
//
// History: 02 May 1995 AlanW Created
//
//+-------------------------------------------------------------------------
inline void UnmarshallRowSeekDescription(
PDeSerStream & stmDeser,
int iVersion,
XPtr<CRowSeekDescription> & xpRowSeek,
BOOL fAllowNull )
{
//
// Deserialize the row seek description
//
ULONG eMethod = stmDeser.GetULong();
switch (eMethod)
{
case eRowSeekNull:
if ( !fAllowNull )
THROW( CException( STATUS_INVALID_PARAMETER ) );
break;
case eRowSeekCurrent:
xpRowSeek.Set( new CRowSeekNext( stmDeser, iVersion ) );
break;
case eRowSeekAt:
xpRowSeek.Set( new CRowSeekAt( stmDeser, iVersion ) );
break;
case eRowSeekAtRatio:
xpRowSeek.Set( new CRowSeekAtRatio( stmDeser, iVersion ) );
break;
case eRowSeekByBookmark:
xpRowSeek.Set( new CRowSeekByBookmark( stmDeser, iVersion ) );
break;
default:
// Don't assert or the pipe hacking test will stop
// Win4Assert( eMethod <= eRowSeekByBookmark );
ciDebugOut(( DEB_ERROR,
"UnmarshallRowSeekDescription, invalid eMethod: %d\n",
eMethod ));
THROW( CException( STATUS_INVALID_PARAMETER ) );
}
}