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