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

527 lines
19 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 2000.
//
// File: rowset.hxx
//
// Contents: Declarations of classes which implement IRowset and
// related OLE DB interfaces over file stores.
//
// Classes: CRowset - cached table over file stores
//
// History: 05 Nov 94 AlanW Created
//
//----------------------------------------------------------------------------
#pragma once
#include <coldesc.hxx>
#include <pidmap.hxx>
#include <rowseek.hxx>
#include <conpt.hxx>
#include <hraccess.hxx>
#include <rstprop.hxx>
#include <proprst.hxx>
#include <proputl.hxx>
#include <srvprvdr.h> // IServiceProperties
class PQuery;
class XRowsInfo;
class CRowBufferSet;
class CAccessor;
class CRowsetNotification;
class CRowsetAsynchNotification;
//+---------------------------------------------------------------------------
//
// Class: CRowset
//
// Purpose: Large table interface for file stores.
//
// Interface: IRowsetScroll and its superclasses.
//
// History: 05 Nov 94 AlanW Created
// 28 Mar 95 BartoszM Added IRowsetWatchRegion
// 03 Sep 99 KLam Reinstated _ConvertOffsetstoPointers
//
// Notes: Supports IRowset, IDBAsynchStatus, IRowsetInfo, IRowsetLocate,
// IRowsetScroll and IRowsetWatchRegion on
// cached data. Also supports IAccessor, IColumnsInfo and
// IConnectionPointContainer via embedded objects
// Executes in user mode from the client machine.
//
//----------------------------------------------------------------------------
class CRowset : public IRowsetExactScroll, public IAccessor,
public IRowsetInfo, public IRowsetIdentity,
public IDBAsynchStatus, public IConvertType,
public IRowsetWatchRegion, public IRowsetQueryStatus,
public IServiceProperties, public IChapteredRowset,
public IRowsetAsynch //(deprecated)
{
public:
//
// IUnknown methods.
//
STDMETHOD(QueryInterface) ( THIS_ REFIID riid,
LPVOID *ppiuk )
{
return _pControllingUnknown->QueryInterface(riid,ppiuk);
}
STDMETHOD_(ULONG, AddRef) (THIS) { return _pControllingUnknown->AddRef();}
STDMETHOD_(ULONG, Release) (THIS) {return _pControllingUnknown->Release(); }
SCODE RealQueryInterface ( REFIID riid, LPVOID *ppiuk ); // used by _pControllingUnknown
// in aggregation - does QI without delegating to outer unknown
//
// IAccessor methods
//
STDMETHOD(AddRefAccessor) (HACCESSOR hAccessor,
ULONG * pcRefCount);
STDMETHOD(CreateAccessor) (DBACCESSORFLAGS dwBindIO,
DBCOUNTITEM cBindings,
const DBBINDING rgBindings[],
DBLENGTH cbRowSize,
HACCESSOR * phAccessor,
DBBINDSTATUS rgStatus[]);
STDMETHOD(GetBindings) (HACCESSOR hAccessor,
DBACCESSORFLAGS * pdwBindIO,
DBCOUNTITEM * pcBindings,
DBBINDING * * prgBindings) /*const*/;
STDMETHOD(ReleaseAccessor) (HACCESSOR hAccessor,
ULONG * pcRefCount);
//
// IRowset methods
//
STDMETHOD(AddRefRows) (DBCOUNTITEM cRows,
const HROW rghRows [],
DBREFCOUNT rgRefCounts[],
DBROWSTATUS rgRowStatus[]);
STDMETHOD(GetData) (HROW hRow,
HACCESSOR hAccessor,
void * pData) /*const*/;
STDMETHOD(GetNextRows) (HCHAPTER hChapter,
DBROWOFFSET cRowsToSkip,
DBROWCOUNT cRows,
DBCOUNTITEM * pcRowsObtained,
HROW * * prghRows);
STDMETHOD(GetReferencedRowset) (DBORDINAL iOrdinal,
REFIID riid,
IUnknown ** ppReferencedRowset) /*const*/;
STDMETHOD(GetProperties) (const ULONG cPropertyIDSets,
const DBPROPIDSET rgPropertyIDSets[],
ULONG * pcPropertySets,
DBPROPSET ** prgPropertySets);
STDMETHOD(GetSpecification) (REFIID riid,
IUnknown ** ppSpecification);
STDMETHOD(ReleaseRows) (DBCOUNTITEM cRows,
const HROW rghRows [],
DBROWOPTIONS rgRowOptions[],
DBREFCOUNT rgRefCounts[],
DBROWSTATUS rgRowStatus[]);
STDMETHOD(RestartPosition) (HCHAPTER hChapter);
#if 0
//
// IParentRowset methods
//
STDMETHOD(GetChildRowset) (IUnknown * pUnkOuter,
ULONG iOrdinal,
REFIID riid,
IUnknown ** ppRowset);
#endif // 0
//
// IChapteredRowset methods
//
STDMETHOD(AddRefChapter) (HCHAPTER hChapter,
ULONG * pcRefCount);
STDMETHOD(ReleaseChapter) (HCHAPTER hChapter,
ULONG * pcRefCount);
//
// IDBAsynchStatus methods
//
STDMETHOD(Abort) (HCHAPTER hChapter,
ULONG ulOpertation);
STDMETHOD(GetStatus) (HCHAPTER hChapter,
DBASYNCHOP ulOperation,
DBCOUNTITEM * pulProgress,
DBCOUNTITEM * pulProgressMax,
DBASYNCHPHASE * pulAsynchPhase,
LPOLESTR * ppwszStatusText) /*const*/;
//
// IRowsetAsynch methods
// deprecated
//
STDMETHOD(RatioFinished) (DBCOUNTITEM * pulDenominator,
DBCOUNTITEM * pulNumerator,
DBCOUNTITEM * pcRows,
BOOL * pfNewRows) /*const*/;
STDMETHOD(Stop) ( );
//
// IRowsetLocate methods
//
STDMETHOD(Compare) (HCHAPTER hChapter,
DBBKMARK cbBM1,
const BYTE * pBM1,
DBBKMARK cbBM2,
const BYTE * pBM2,
DBCOMPARE * pdwComparison) /*const*/;
STDMETHOD(GetRowsAt) (HWATCHREGION hRegion,
HCHAPTER hChapter,
DBBKMARK cbBookmark,
const BYTE * pBookmark,
DBROWOFFSET lRowsOffset,
DBROWCOUNT cRows,
DBCOUNTITEM * pcRowsObtained,
HROW * * prghRows);
STDMETHOD(GetRowsByBookmark) (HCHAPTER hChapter,
DBCOUNTITEM cRows,
const DBBKMARK rgcbBookmarks[],
const BYTE * rgpBookmarks[],
HROW rghRows[],
DBROWSTATUS rgRowStatus[]);
STDMETHOD(Hash) (HCHAPTER hChapter,
DBBKMARK cBookmarks,
const DBBKMARK rgcbBookmarks[],
const BYTE * rgpBookmarks[],
DBHASHVALUE rgHashedValues[],
DBROWSTATUS rgRowStatus[]);
//
// IRowsetScroll methods
//
STDMETHOD(GetApproximatePosition) (HCHAPTER hChapter,
DBBKMARK cbBookmark,
const BYTE * pBookmark,
DBCOUNTITEM * pulPosition,
DBCOUNTITEM * pcRows) /*const*/;
STDMETHOD(GetRowsAtRatio) (HWATCHREGION hRegion,
HCHAPTER hChapter,
DBCOUNTITEM ulNumerator,
DBCOUNTITEM ulDenominator,
DBROWCOUNT cRows,
DBCOUNTITEM * pcRowsObtained,
HROW * * prghRows);
//
// IRowsetExactScroll methods
// deprecated
//
STDMETHOD(GetExactPosition) (HCHAPTER hChapter,
DBBKMARK cbBookmark,
const BYTE * pBookmark,
DBCOUNTITEM * pulPosition,
DBCOUNTITEM * pcRows) /*const*/;
//
// IRowsetIdentity methods
//
STDMETHOD(IsSameRow) (HROW hThisRow,
HROW hThatRow);
//
// IRowsetWatchAll methods
//
STDMETHOD(Acknowledge) ( );
STDMETHOD(Start) ( );
STDMETHOD(StopWatching) ( );
//
// IRowsetWatchRegion methods
//
STDMETHOD(CreateWatchRegion) (
DBWATCHMODE mode,
HWATCHREGION* phRegion);
STDMETHOD(ChangeWatchMode) (
HWATCHREGION hRegion,
DBWATCHMODE mode);
STDMETHOD(DeleteWatchRegion) (
HWATCHREGION hRegion);
STDMETHOD(GetWatchRegionInfo) (
HWATCHREGION hRegion,
DBWATCHMODE * pMode,
HCHAPTER * phChapter,
DBBKMARK * pcbBookmark,
BYTE * * ppBookmark,
DBROWCOUNT * pcRows);
STDMETHOD(Refresh) (
DBCOUNTITEM* pChangesObtained,
DBROWWATCHCHANGE** prgChanges );
STDMETHOD(ShrinkWatchRegion) (
HWATCHREGION hRegion,
HCHAPTER hChapter,
DBBKMARK cbBookmark,
BYTE* pBookmark,
DBROWCOUNT cRows );
//
// IConvertType methods
//
STDMETHOD(CanConvert) (DBTYPE wFromType,
DBTYPE wToType,
DBCONVERTFLAGS dwConvertFlags );
//
// IRowsetQueryStatus methods
//
STDMETHOD(GetStatus) (DWORD * pStatus);
STDMETHOD(GetStatusEx) (DWORD * pStatus,
DWORD * pcFilteredDocuments,
DWORD * pcDocumentsToFilter,
DBCOUNTITEM * pdwRatioFinishedDenominator,
DBCOUNTITEM * pdwRatioFinishedNumerator,
DBBKMARK cbBmk,
const BYTE * pBmk,
DBCOUNTITEM * piRowCurrent,
DBCOUNTITEM * pcRowsTotal );
//
// IServiceProperties methods
//
#if 0
STDMETHOD(GetProperties) (
/* [in] */ ULONG cPropertyIDSets,
/* [size_is][in] */ const DBPROPIDSET rgPropertyIDSets[ ],
/* [out][in] */ ULONG *pcPropertySets,
/* [size_is][size_is][out] */ DBPROPSET **prgPropertySets);
#endif // 0
STDMETHOD(GetPropertyInfo) (
/* [in] */ ULONG cPropertyIDSets,
/* [size_is][in] */ const DBPROPIDSET rgPropertyIDSets[ ],
/* [out][in] */ ULONG *pcPropertyInfoSets,
/* [size_is][size_is][out] */ DBPROPINFOSET **prgPropertyInfoSets,
/* [out] */ OLECHAR **ppDescBuffer);
STDMETHOD(SetRequestedProperties) (
/* [in] */ ULONG cPropertySets,
/* [size_is][out][in] */ DBPROPSET rgPropertySets[ ]);
STDMETHOD(SetSuppliedProperties) (
/* [in] */ ULONG cPropertySets,
/* [size_is][out][in] */ DBPROPSET rgPropertySets[ ]);
//
// Local methods.
//
CRowset( IUnknown * pUnkOuter,
IUnknown ** ppMyUnk,
CColumnSet const & cols,
CPidMapperWithNames const & pidmap,
PQuery & rQuery,
IUnknown & rControllingQuery,
BOOL fIsCategorized,
XPtr<CMRowsetProps> & xProps,
ULONG hCursor,
CAccessorBag & aAccessors,
IUnknown * pUnkCreator );
virtual ~CRowset();
void SetRelatedRowset( CRowset * pRowset ) {
_pRelatedRowset = pRowset;
pRowset->SetChapterRowbufs( _pRowBufs );
}
#ifdef CIEXTMODE
void CiExtDump(void *ciExtSelf);
#endif
private:
void SetChapterRowbufs( CRowBufferSet * pChapHelper ) {
Win4Assert( 0 == _pChapterRowbufs );
_pChapterRowbufs = pChapHelper;
}
// could use CImpIUnknown from impiunk.hxx except _rControllingQuery isn't
// used in general case.
class CImpIUnknown:public IUnknown
{
friend class CRowset;
public:
CImpIUnknown( IUnknown & rControllingQuery, CRowset * pRowset):
_ref(0), _rControllingQuery(rControllingQuery), _pRowset(pRowset)
{}
~CImpIUnknown() {};
//
// IUnknown methods.
//
STDMETHOD(QueryInterface) ( THIS_ REFIID riid,
LPVOID *ppiuk )
{ SCODE sc= S_OK;
if (IID_IUnknown == riid)
*ppiuk = this;
else
sc = _pRowset->RealQueryInterface(riid, ppiuk);
if ( SUCCEEDED( sc) )
((IUnknown *) *ppiuk)->AddRef();
return sc;
}
STDMETHOD_(ULONG, AddRef) (THIS);
STDMETHOD_(ULONG, Release) (THIS);
private:
long _ref; // OLE reference count
IUnknown & _rControllingQuery; // likely IQuery
CRowset * _pRowset;
};
void _ValidateColumnMappings();
#ifdef _WIN64
void _ConvertOffsetsToPointers( BYTE * pbRows,
BYTE * pbBias,
unsigned cRows,
CFixedVarAllocator *pArrayAlloc );
#endif
SCODE _FetchRows( CRowSeekDescription & rSeekDesc,
DBROWCOUNT cRows,
DBCOUNTITEM * pcRowsReturned,
HROW * * prghRows
);
DBROWSTATUS _MapBookmarkNoThrow( DBBKMARK cbBookmark,
const BYTE * pBookmark,
CI_TBL_BMK & rBmk) const;
CI_TBL_BMK _MapBookmark( DBBKMARK cbBmk,
const BYTE * pBmk ) const;
CI_TBL_CHAPT _MapChapter( HCHAPTER hChapter ) const;
PQuery & _rQuery; // The cached table/query (or proxy)
CMutexSem _mutex; // synchronizes access
XPtr<CMRowsetProps> _xProperties; // Rowset properties
ULONG _hCursor; // A handle to the table cursor
BOOL _fForwardOnly; // If TRUE, a forward-only Rowset
BOOL _fHoldRows; // if TRUE, forward-only Rowset can
// hold onto HROWs on GetNextRows
BOOL _fIsCategorized; // i.e. not a highest-level rowset,
// so chapter args must be non-zero
BOOL _fExtendedTypes; // if TRUE, okay to use PROPVARIANT
// instead of VARIANT
BOOL _fAsynchronous; // if TRUE, rowset is populated
// asynchronously
CRowBufferSet * _pRowBufs; // Buffered rows
BOOL _fPossibleOffsetConversions; // if TRUE, there could be offset
// conversion needed
//
// IConnectionPointContainer and notification support
//
CConnectionPointContainer * _pConnectionPointContainer;
XInterface<CRowsetNotification> _pRowsetNotification;
// Note: _pAsynchNotification is not owned by the recordset, it's an
// alias to _pRowsetNotification.
CRowsetAsynchNotification * _pAsynchNotification;
CColumnsInfo _ColumnsInfo; // Column information
CAccessorBag _aAccessors;
CMDSPropInfo _PropInfo; // IServiceProperties::GetPropertyInfo
IUnknown * _pControllingUnknown; // outer unknown
IRowset * _pRelatedRowset; // for GetRelatedRowset
CRowBufferSet * _pChapterRowbufs; // for IChapteredRowset
CImpIUnknown _impIUnknown;
//
// Support Ole DB error handling
//
CCIOleDBError _DBErrorObj;
// OLE DB Data Conversion Library Interface
// One IDataConvert interface is kept in each rowset object and is passed
// down in GetData function of the accessor. The IDataConvert interface is
// instantiated(by the lower lever conversion routine) only when needed for
// data conversion and then is kept in this smart interface pointer for
// the life of the rowset object.
XInterface<IDataConvert> _xDataConvert;
//
// Pointer to the command or session object which created this rowset.
// Used to implement IRowsetInfo::GetSpecification()
//
XInterface<IUnknown> _xUnkCreator;
};