Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

526 lines
19 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 2000.
  5. //
  6. // File: rowset.hxx
  7. //
  8. // Contents: Declarations of classes which implement IRowset and
  9. // related OLE DB interfaces over file stores.
  10. //
  11. // Classes: CRowset - cached table over file stores
  12. //
  13. // History: 05 Nov 94 AlanW Created
  14. //
  15. //----------------------------------------------------------------------------
  16. #pragma once
  17. #include <coldesc.hxx>
  18. #include <pidmap.hxx>
  19. #include <rowseek.hxx>
  20. #include <conpt.hxx>
  21. #include <hraccess.hxx>
  22. #include <rstprop.hxx>
  23. #include <proprst.hxx>
  24. #include <proputl.hxx>
  25. #include <srvprvdr.h> // IServiceProperties
  26. class PQuery;
  27. class XRowsInfo;
  28. class CRowBufferSet;
  29. class CAccessor;
  30. class CRowsetNotification;
  31. class CRowsetAsynchNotification;
  32. //+---------------------------------------------------------------------------
  33. //
  34. // Class: CRowset
  35. //
  36. // Purpose: Large table interface for file stores.
  37. //
  38. // Interface: IRowsetScroll and its superclasses.
  39. //
  40. // History: 05 Nov 94 AlanW Created
  41. // 28 Mar 95 BartoszM Added IRowsetWatchRegion
  42. // 03 Sep 99 KLam Reinstated _ConvertOffsetstoPointers
  43. //
  44. // Notes: Supports IRowset, IDBAsynchStatus, IRowsetInfo, IRowsetLocate,
  45. // IRowsetScroll and IRowsetWatchRegion on
  46. // cached data. Also supports IAccessor, IColumnsInfo and
  47. // IConnectionPointContainer via embedded objects
  48. // Executes in user mode from the client machine.
  49. //
  50. //----------------------------------------------------------------------------
  51. class CRowset : public IRowsetExactScroll, public IAccessor,
  52. public IRowsetInfo, public IRowsetIdentity,
  53. public IDBAsynchStatus, public IConvertType,
  54. public IRowsetWatchRegion, public IRowsetQueryStatus,
  55. public IServiceProperties, public IChapteredRowset,
  56. public IRowsetAsynch //(deprecated)
  57. {
  58. public:
  59. //
  60. // IUnknown methods.
  61. //
  62. STDMETHOD(QueryInterface) ( THIS_ REFIID riid,
  63. LPVOID *ppiuk )
  64. {
  65. return _pControllingUnknown->QueryInterface(riid,ppiuk);
  66. }
  67. STDMETHOD_(ULONG, AddRef) (THIS) { return _pControllingUnknown->AddRef();}
  68. STDMETHOD_(ULONG, Release) (THIS) {return _pControllingUnknown->Release(); }
  69. SCODE RealQueryInterface ( REFIID riid, LPVOID *ppiuk ); // used by _pControllingUnknown
  70. // in aggregation - does QI without delegating to outer unknown
  71. //
  72. // IAccessor methods
  73. //
  74. STDMETHOD(AddRefAccessor) (HACCESSOR hAccessor,
  75. ULONG * pcRefCount);
  76. STDMETHOD(CreateAccessor) (DBACCESSORFLAGS dwBindIO,
  77. DBCOUNTITEM cBindings,
  78. const DBBINDING rgBindings[],
  79. DBLENGTH cbRowSize,
  80. HACCESSOR * phAccessor,
  81. DBBINDSTATUS rgStatus[]);
  82. STDMETHOD(GetBindings) (HACCESSOR hAccessor,
  83. DBACCESSORFLAGS * pdwBindIO,
  84. DBCOUNTITEM * pcBindings,
  85. DBBINDING * * prgBindings) /*const*/;
  86. STDMETHOD(ReleaseAccessor) (HACCESSOR hAccessor,
  87. ULONG * pcRefCount);
  88. //
  89. // IRowset methods
  90. //
  91. STDMETHOD(AddRefRows) (DBCOUNTITEM cRows,
  92. const HROW rghRows [],
  93. DBREFCOUNT rgRefCounts[],
  94. DBROWSTATUS rgRowStatus[]);
  95. STDMETHOD(GetData) (HROW hRow,
  96. HACCESSOR hAccessor,
  97. void * pData) /*const*/;
  98. STDMETHOD(GetNextRows) (HCHAPTER hChapter,
  99. DBROWOFFSET cRowsToSkip,
  100. DBROWCOUNT cRows,
  101. DBCOUNTITEM * pcRowsObtained,
  102. HROW * * prghRows);
  103. STDMETHOD(GetReferencedRowset) (DBORDINAL iOrdinal,
  104. REFIID riid,
  105. IUnknown ** ppReferencedRowset) /*const*/;
  106. STDMETHOD(GetProperties) (const ULONG cPropertyIDSets,
  107. const DBPROPIDSET rgPropertyIDSets[],
  108. ULONG * pcPropertySets,
  109. DBPROPSET ** prgPropertySets);
  110. STDMETHOD(GetSpecification) (REFIID riid,
  111. IUnknown ** ppSpecification);
  112. STDMETHOD(ReleaseRows) (DBCOUNTITEM cRows,
  113. const HROW rghRows [],
  114. DBROWOPTIONS rgRowOptions[],
  115. DBREFCOUNT rgRefCounts[],
  116. DBROWSTATUS rgRowStatus[]);
  117. STDMETHOD(RestartPosition) (HCHAPTER hChapter);
  118. #if 0
  119. //
  120. // IParentRowset methods
  121. //
  122. STDMETHOD(GetChildRowset) (IUnknown * pUnkOuter,
  123. ULONG iOrdinal,
  124. REFIID riid,
  125. IUnknown ** ppRowset);
  126. #endif // 0
  127. //
  128. // IChapteredRowset methods
  129. //
  130. STDMETHOD(AddRefChapter) (HCHAPTER hChapter,
  131. ULONG * pcRefCount);
  132. STDMETHOD(ReleaseChapter) (HCHAPTER hChapter,
  133. ULONG * pcRefCount);
  134. //
  135. // IDBAsynchStatus methods
  136. //
  137. STDMETHOD(Abort) (HCHAPTER hChapter,
  138. ULONG ulOpertation);
  139. STDMETHOD(GetStatus) (HCHAPTER hChapter,
  140. DBASYNCHOP ulOperation,
  141. DBCOUNTITEM * pulProgress,
  142. DBCOUNTITEM * pulProgressMax,
  143. DBASYNCHPHASE * pulAsynchPhase,
  144. LPOLESTR * ppwszStatusText) /*const*/;
  145. //
  146. // IRowsetAsynch methods
  147. // deprecated
  148. //
  149. STDMETHOD(RatioFinished) (DBCOUNTITEM * pulDenominator,
  150. DBCOUNTITEM * pulNumerator,
  151. DBCOUNTITEM * pcRows,
  152. BOOL * pfNewRows) /*const*/;
  153. STDMETHOD(Stop) ( );
  154. //
  155. // IRowsetLocate methods
  156. //
  157. STDMETHOD(Compare) (HCHAPTER hChapter,
  158. DBBKMARK cbBM1,
  159. const BYTE * pBM1,
  160. DBBKMARK cbBM2,
  161. const BYTE * pBM2,
  162. DBCOMPARE * pdwComparison) /*const*/;
  163. STDMETHOD(GetRowsAt) (HWATCHREGION hRegion,
  164. HCHAPTER hChapter,
  165. DBBKMARK cbBookmark,
  166. const BYTE * pBookmark,
  167. DBROWOFFSET lRowsOffset,
  168. DBROWCOUNT cRows,
  169. DBCOUNTITEM * pcRowsObtained,
  170. HROW * * prghRows);
  171. STDMETHOD(GetRowsByBookmark) (HCHAPTER hChapter,
  172. DBCOUNTITEM cRows,
  173. const DBBKMARK rgcbBookmarks[],
  174. const BYTE * rgpBookmarks[],
  175. HROW rghRows[],
  176. DBROWSTATUS rgRowStatus[]);
  177. STDMETHOD(Hash) (HCHAPTER hChapter,
  178. DBBKMARK cBookmarks,
  179. const DBBKMARK rgcbBookmarks[],
  180. const BYTE * rgpBookmarks[],
  181. DBHASHVALUE rgHashedValues[],
  182. DBROWSTATUS rgRowStatus[]);
  183. //
  184. // IRowsetScroll methods
  185. //
  186. STDMETHOD(GetApproximatePosition) (HCHAPTER hChapter,
  187. DBBKMARK cbBookmark,
  188. const BYTE * pBookmark,
  189. DBCOUNTITEM * pulPosition,
  190. DBCOUNTITEM * pcRows) /*const*/;
  191. STDMETHOD(GetRowsAtRatio) (HWATCHREGION hRegion,
  192. HCHAPTER hChapter,
  193. DBCOUNTITEM ulNumerator,
  194. DBCOUNTITEM ulDenominator,
  195. DBROWCOUNT cRows,
  196. DBCOUNTITEM * pcRowsObtained,
  197. HROW * * prghRows);
  198. //
  199. // IRowsetExactScroll methods
  200. // deprecated
  201. //
  202. STDMETHOD(GetExactPosition) (HCHAPTER hChapter,
  203. DBBKMARK cbBookmark,
  204. const BYTE * pBookmark,
  205. DBCOUNTITEM * pulPosition,
  206. DBCOUNTITEM * pcRows) /*const*/;
  207. //
  208. // IRowsetIdentity methods
  209. //
  210. STDMETHOD(IsSameRow) (HROW hThisRow,
  211. HROW hThatRow);
  212. //
  213. // IRowsetWatchAll methods
  214. //
  215. STDMETHOD(Acknowledge) ( );
  216. STDMETHOD(Start) ( );
  217. STDMETHOD(StopWatching) ( );
  218. //
  219. // IRowsetWatchRegion methods
  220. //
  221. STDMETHOD(CreateWatchRegion) (
  222. DBWATCHMODE mode,
  223. HWATCHREGION* phRegion);
  224. STDMETHOD(ChangeWatchMode) (
  225. HWATCHREGION hRegion,
  226. DBWATCHMODE mode);
  227. STDMETHOD(DeleteWatchRegion) (
  228. HWATCHREGION hRegion);
  229. STDMETHOD(GetWatchRegionInfo) (
  230. HWATCHREGION hRegion,
  231. DBWATCHMODE * pMode,
  232. HCHAPTER * phChapter,
  233. DBBKMARK * pcbBookmark,
  234. BYTE * * ppBookmark,
  235. DBROWCOUNT * pcRows);
  236. STDMETHOD(Refresh) (
  237. DBCOUNTITEM* pChangesObtained,
  238. DBROWWATCHCHANGE** prgChanges );
  239. STDMETHOD(ShrinkWatchRegion) (
  240. HWATCHREGION hRegion,
  241. HCHAPTER hChapter,
  242. DBBKMARK cbBookmark,
  243. BYTE* pBookmark,
  244. DBROWCOUNT cRows );
  245. //
  246. // IConvertType methods
  247. //
  248. STDMETHOD(CanConvert) (DBTYPE wFromType,
  249. DBTYPE wToType,
  250. DBCONVERTFLAGS dwConvertFlags );
  251. //
  252. // IRowsetQueryStatus methods
  253. //
  254. STDMETHOD(GetStatus) (DWORD * pStatus);
  255. STDMETHOD(GetStatusEx) (DWORD * pStatus,
  256. DWORD * pcFilteredDocuments,
  257. DWORD * pcDocumentsToFilter,
  258. DBCOUNTITEM * pdwRatioFinishedDenominator,
  259. DBCOUNTITEM * pdwRatioFinishedNumerator,
  260. DBBKMARK cbBmk,
  261. const BYTE * pBmk,
  262. DBCOUNTITEM * piRowCurrent,
  263. DBCOUNTITEM * pcRowsTotal );
  264. //
  265. // IServiceProperties methods
  266. //
  267. #if 0
  268. STDMETHOD(GetProperties) (
  269. /* [in] */ ULONG cPropertyIDSets,
  270. /* [size_is][in] */ const DBPROPIDSET rgPropertyIDSets[ ],
  271. /* [out][in] */ ULONG *pcPropertySets,
  272. /* [size_is][size_is][out] */ DBPROPSET **prgPropertySets);
  273. #endif // 0
  274. STDMETHOD(GetPropertyInfo) (
  275. /* [in] */ ULONG cPropertyIDSets,
  276. /* [size_is][in] */ const DBPROPIDSET rgPropertyIDSets[ ],
  277. /* [out][in] */ ULONG *pcPropertyInfoSets,
  278. /* [size_is][size_is][out] */ DBPROPINFOSET **prgPropertyInfoSets,
  279. /* [out] */ OLECHAR **ppDescBuffer);
  280. STDMETHOD(SetRequestedProperties) (
  281. /* [in] */ ULONG cPropertySets,
  282. /* [size_is][out][in] */ DBPROPSET rgPropertySets[ ]);
  283. STDMETHOD(SetSuppliedProperties) (
  284. /* [in] */ ULONG cPropertySets,
  285. /* [size_is][out][in] */ DBPROPSET rgPropertySets[ ]);
  286. //
  287. // Local methods.
  288. //
  289. CRowset( IUnknown * pUnkOuter,
  290. IUnknown ** ppMyUnk,
  291. CColumnSet const & cols,
  292. CPidMapperWithNames const & pidmap,
  293. PQuery & rQuery,
  294. IUnknown & rControllingQuery,
  295. BOOL fIsCategorized,
  296. XPtr<CMRowsetProps> & xProps,
  297. ULONG hCursor,
  298. CAccessorBag & aAccessors,
  299. IUnknown * pUnkCreator );
  300. virtual ~CRowset();
  301. void SetRelatedRowset( CRowset * pRowset ) {
  302. _pRelatedRowset = pRowset;
  303. pRowset->SetChapterRowbufs( _pRowBufs );
  304. }
  305. #ifdef CIEXTMODE
  306. void CiExtDump(void *ciExtSelf);
  307. #endif
  308. private:
  309. void SetChapterRowbufs( CRowBufferSet * pChapHelper ) {
  310. Win4Assert( 0 == _pChapterRowbufs );
  311. _pChapterRowbufs = pChapHelper;
  312. }
  313. // could use CImpIUnknown from impiunk.hxx except _rControllingQuery isn't
  314. // used in general case.
  315. class CImpIUnknown:public IUnknown
  316. {
  317. friend class CRowset;
  318. public:
  319. CImpIUnknown( IUnknown & rControllingQuery, CRowset * pRowset):
  320. _ref(0), _rControllingQuery(rControllingQuery), _pRowset(pRowset)
  321. {}
  322. ~CImpIUnknown() {};
  323. //
  324. // IUnknown methods.
  325. //
  326. STDMETHOD(QueryInterface) ( THIS_ REFIID riid,
  327. LPVOID *ppiuk )
  328. { SCODE sc= S_OK;
  329. if (IID_IUnknown == riid)
  330. *ppiuk = this;
  331. else
  332. sc = _pRowset->RealQueryInterface(riid, ppiuk);
  333. if ( SUCCEEDED( sc) )
  334. ((IUnknown *) *ppiuk)->AddRef();
  335. return sc;
  336. }
  337. STDMETHOD_(ULONG, AddRef) (THIS);
  338. STDMETHOD_(ULONG, Release) (THIS);
  339. private:
  340. long _ref; // OLE reference count
  341. IUnknown & _rControllingQuery; // likely IQuery
  342. CRowset * _pRowset;
  343. };
  344. void _ValidateColumnMappings();
  345. #ifdef _WIN64
  346. void _ConvertOffsetsToPointers( BYTE * pbRows,
  347. BYTE * pbBias,
  348. unsigned cRows,
  349. CFixedVarAllocator *pArrayAlloc );
  350. #endif
  351. SCODE _FetchRows( CRowSeekDescription & rSeekDesc,
  352. DBROWCOUNT cRows,
  353. DBCOUNTITEM * pcRowsReturned,
  354. HROW * * prghRows
  355. );
  356. DBROWSTATUS _MapBookmarkNoThrow( DBBKMARK cbBookmark,
  357. const BYTE * pBookmark,
  358. CI_TBL_BMK & rBmk) const;
  359. CI_TBL_BMK _MapBookmark( DBBKMARK cbBmk,
  360. const BYTE * pBmk ) const;
  361. CI_TBL_CHAPT _MapChapter( HCHAPTER hChapter ) const;
  362. PQuery & _rQuery; // The cached table/query (or proxy)
  363. CMutexSem _mutex; // synchronizes access
  364. XPtr<CMRowsetProps> _xProperties; // Rowset properties
  365. ULONG _hCursor; // A handle to the table cursor
  366. BOOL _fForwardOnly; // If TRUE, a forward-only Rowset
  367. BOOL _fHoldRows; // if TRUE, forward-only Rowset can
  368. // hold onto HROWs on GetNextRows
  369. BOOL _fIsCategorized; // i.e. not a highest-level rowset,
  370. // so chapter args must be non-zero
  371. BOOL _fExtendedTypes; // if TRUE, okay to use PROPVARIANT
  372. // instead of VARIANT
  373. BOOL _fAsynchronous; // if TRUE, rowset is populated
  374. // asynchronously
  375. CRowBufferSet * _pRowBufs; // Buffered rows
  376. BOOL _fPossibleOffsetConversions; // if TRUE, there could be offset
  377. // conversion needed
  378. //
  379. // IConnectionPointContainer and notification support
  380. //
  381. CConnectionPointContainer * _pConnectionPointContainer;
  382. XInterface<CRowsetNotification> _pRowsetNotification;
  383. // Note: _pAsynchNotification is not owned by the recordset, it's an
  384. // alias to _pRowsetNotification.
  385. CRowsetAsynchNotification * _pAsynchNotification;
  386. CColumnsInfo _ColumnsInfo; // Column information
  387. CAccessorBag _aAccessors;
  388. CMDSPropInfo _PropInfo; // IServiceProperties::GetPropertyInfo
  389. IUnknown * _pControllingUnknown; // outer unknown
  390. IRowset * _pRelatedRowset; // for GetRelatedRowset
  391. CRowBufferSet * _pChapterRowbufs; // for IChapteredRowset
  392. CImpIUnknown _impIUnknown;
  393. //
  394. // Support Ole DB error handling
  395. //
  396. CCIOleDBError _DBErrorObj;
  397. // OLE DB Data Conversion Library Interface
  398. // One IDataConvert interface is kept in each rowset object and is passed
  399. // down in GetData function of the accessor. The IDataConvert interface is
  400. // instantiated(by the lower lever conversion routine) only when needed for
  401. // data conversion and then is kept in this smart interface pointer for
  402. // the life of the rowset object.
  403. XInterface<IDataConvert> _xDataConvert;
  404. //
  405. // Pointer to the command or session object which created this rowset.
  406. // Used to implement IRowsetInfo::GetSpecification()
  407. //
  408. XInterface<IUnknown> _xUnkCreator;
  409. };