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.

499 lines
16 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1998.
  5. //
  6. // File: tablecol.hxx
  7. //
  8. // Contents: Column descriptions used by CLargeTable.
  9. //
  10. // Classes: CColumnMasterDesc
  11. // CTableColumn
  12. //
  13. // CColumnMasterArray
  14. // CTableColumnArray
  15. //
  16. // CColumnMasterSet
  17. // CTableColumnSet
  18. //
  19. // History: 15 Sep 94 AlanW Split out from coldesc.hxx
  20. // 12 Feb 95 AlanW Updated fields and accessors in
  21. // CTableColumn for OLE-DB phase III
  22. //
  23. //--------------------------------------------------------------------------
  24. #pragma once
  25. class CTableVariant;
  26. class PVarAllocator;
  27. class CCompressedCol;
  28. class SSortKey;
  29. #include <pidmap.hxx>
  30. //+-------------------------------------------------------------------------
  31. //
  32. // Class: CColumnMasterDesc
  33. //
  34. // Purpose: A description of a column which is known to a table
  35. // because it is a bound output column, a computed column,
  36. // or a column in a sort key.
  37. //
  38. // Interface:
  39. //
  40. // Notes:
  41. //
  42. //--------------------------------------------------------------------------
  43. class CColumnMasterDesc
  44. {
  45. friend class CColumnMasterSet;
  46. public:
  47. CColumnMasterDesc(PROPID PropIdent = 0,
  48. VARTYPE DatType = VT_EMPTY);
  49. CColumnMasterDesc(SSortKey& rSortKey);
  50. ~CColumnMasterDesc();
  51. void SetCompression( CCompressedCol* pCompr,
  52. PROPID SharedID = 0);
  53. void SetComputed(BOOL fComputed)
  54. { _fComputedProperty = fComputed; }
  55. void SetUniform(BOOL fUniform)
  56. { _fUniformType = fUniform; }
  57. void SetNotVariant(BOOL fNotVariant)
  58. { _fNotVariantType = fNotVariant; }
  59. BOOL IsCompressedCol() const { return 0 != _pCompression; }
  60. CCompressedCol * GetCompressor() const {
  61. return _pCompression;
  62. }
  63. PROPID GetCompressMasterId() const { return _CompressMasterID; }
  64. PROPID PropId; // Property ID in table
  65. VARTYPE DataType; // most restrictive variant type in which
  66. // all known values can be expressed.
  67. VARTYPE _PredominantType; // most frequently occuring variant type
  68. USHORT _cbData; // required width in segment row data
  69. int _fComputedProperty:1; // TRUE if generated column. In this
  70. // case, PropId gives a special prop. ID
  71. int _fUniformType:1; // TRUE if all data are of type
  72. // _PredominantType
  73. int _fNotVariantType:1; // TRUE if it is absolutely known that
  74. // the type cannot vary (e.g., system
  75. // properties, some computed properties)
  76. private:
  77. CCompressedCol* _pCompression; // global compressor
  78. PROPID _CompressMasterID; // if !0, shared compression
  79. };
  80. //+-------------------------------------------------------------------------
  81. //
  82. // Class: CTableColumn
  83. //
  84. // Purpose: A description of a column stored in a table segment.
  85. // Also used for transfer of data between the table and
  86. // rowset, and for describing the format of row buffers
  87. // in the rowset.
  88. //
  89. // Interface:
  90. //
  91. //--------------------------------------------------------------------------
  92. class CTableColumn
  93. {
  94. public:
  95. enum StoreParts {
  96. StorePartValue = 0x1,
  97. StorePartStatus = 0x2,
  98. StorePartLength = 0x4,
  99. };
  100. enum StoreStatus
  101. {
  102. StoreStatusOK = 0,
  103. StoreStatusDeferred = 1,
  104. StoreStatusNull = 2,
  105. };
  106. CTableColumn( PROPID propid = 0, VARTYPE type = VT_NULL ):
  107. PropId( propid ),
  108. _obValue( 0 ), _cbValue( 0 ),
  109. _obStatus( 0 ), _obLength( 0 ),
  110. _usStoreParts( 0 ),
  111. _StoreAsType( type ), _PredominantType( type ),
  112. _fUniformType( TRUE ),
  113. _pCompression( 0 ),
  114. _fGlobalCompr( FALSE ), _CompressMasterID( 0 ),
  115. _fSpecial( FALSE ),
  116. _fPartialDeferred( FALSE )
  117. { }
  118. CTableColumn( CTableColumn & src ):
  119. PropId( src.PropId ),
  120. _obValue( 0 ), _cbValue( 0 ),
  121. _obStatus( 0 ), _obLength( 0 ),
  122. _usStoreParts( 0 ),
  123. _StoreAsType( src._StoreAsType ),
  124. _PredominantType( src._PredominantType ),
  125. _fGlobalCompr( src._fGlobalCompr ),
  126. _fUniformType( src._fUniformType ),
  127. _pCompression( 0 ),
  128. _CompressMasterID( src._CompressMasterID ),
  129. _fSpecial( FALSE ),
  130. _fPartialDeferred( src._fPartialDeferred )
  131. {
  132. if ( _fGlobalCompr )
  133. {
  134. _pCompression = src._pCompression;
  135. _obValue = src._obValue;
  136. _cbValue = src._cbValue;
  137. _obLength = src._obLength;
  138. _obStatus = src._obStatus;
  139. Win4Assert( src.StorePartStatus & src._usStoreParts );
  140. _usStoreParts = ( StorePartValue | StorePartStatus );
  141. }
  142. }
  143. ~CTableColumn( );
  144. PROPID GetPropId() const { return PropId; }
  145. void SetPropId( PROPID val ) { PropId = val; }
  146. void SetGlobalCompressor( CCompressedCol* pCompr,
  147. PROPID SharedID = 0) {
  148. _pCompression = pCompr;
  149. _CompressMasterID = SharedID;
  150. _fGlobalCompr = TRUE;
  151. }
  152. void SetLocalCompressor( CCompressedCol * pCompr,
  153. PROPID SharedId = 0 )
  154. {
  155. _pCompression = pCompr;
  156. _CompressMasterID = SharedId;
  157. _fGlobalCompr = FALSE;
  158. }
  159. USHORT GetValueOffset() const {
  160. return _obValue;
  161. }
  162. USHORT GetValueSize() const {
  163. return _cbValue;
  164. }
  165. USHORT GetStatusOffset() const {
  166. return _obStatus;
  167. }
  168. size_t GetStatusSize() const {
  169. return sizeof (BYTE);
  170. }
  171. USHORT GetLengthOffset() const {
  172. return _obLength;
  173. }
  174. size_t GetLengthSize() const {
  175. return sizeof (ULONG);
  176. }
  177. VARTYPE GetStoredType() const {
  178. return _StoreAsType;
  179. }
  180. CCompressedCol * GetCompressor() const {
  181. return _pCompression;
  182. }
  183. BOOL IsCompressedCol() const {
  184. return 0 != _pCompression;
  185. }
  186. BOOL IsGlobalCompressedCol() const {
  187. return _fGlobalCompr;
  188. }
  189. PROPID GetCompressMasterId() const {
  190. return _CompressMasterID;
  191. }
  192. // Copy a column from table to table or to row buffer
  193. DBSTATUS CopyColumnData(
  194. BYTE * pbDstRow,
  195. CTableColumn const & rDstColumn,
  196. PVarAllocator & rDstPool,
  197. BYTE * pbSrcRow,
  198. PVarAllocator & rSrcPool);
  199. // Create a CTableVariant from from buffered data
  200. BOOL CreateVariant(
  201. CTableVariant & rVarnt,
  202. BYTE * pbSrc,
  203. PVarAllocator & rSrcPool) const;
  204. void SetValueField(VARTYPE vt, USHORT obValue, USHORT cbValue) {
  205. _StoreAsType = vt;
  206. _obValue = obValue;
  207. _cbValue = cbValue;
  208. _usStoreParts |= StorePartValue;
  209. }
  210. void SetStatusField(USHORT obStatus, USHORT cbStatus) {
  211. Win4Assert(cbStatus == sizeof (BYTE));
  212. _obStatus = obStatus;
  213. _usStoreParts |= StorePartStatus;
  214. }
  215. void SetLengthField(USHORT obLength, USHORT cbLength) {
  216. Win4Assert(cbLength == sizeof (ULONG));
  217. _obLength = obLength;
  218. _usStoreParts |= StorePartLength;
  219. }
  220. BOOL IsValueStored() const {
  221. return _usStoreParts & StorePartValue;
  222. }
  223. BOOL IsStatusStored() const {
  224. Win4Assert( _usStoreParts & StorePartStatus );
  225. return TRUE;
  226. }
  227. BOOL IsLengthStored() const {
  228. return _usStoreParts & StorePartLength;
  229. }
  230. StoreStatus GetStatus( const BYTE * pb ) const
  231. {
  232. Win4Assert( IsStatusStored() );
  233. return (StoreStatus) ( * ( pb + GetStatusOffset() ) );
  234. }
  235. BOOL IsDeferred(BYTE *pb) const
  236. {
  237. Win4Assert( IsStatusStored() );
  238. return ( StoreStatusDeferred == GetStatus( pb ) );
  239. }
  240. inline BOOL IsPartialDeferred() const
  241. {
  242. return _fPartialDeferred;
  243. }
  244. BOOL IsNull(BYTE *pb) const
  245. {
  246. Win4Assert( IsStatusStored() );
  247. return ( StoreStatusNull == GetStatus( pb ) );
  248. }
  249. ULONG GetLength(BYTE *pb) const
  250. {
  251. Win4Assert( IsLengthStored() );
  252. return * (ULONG *) ( pb + GetLengthOffset() );
  253. }
  254. void SetStatus(BYTE *pb, StoreStatus stat) const
  255. {
  256. Win4Assert( IsStatusStored() );
  257. * (pb + GetStatusOffset() ) = stat;
  258. }
  259. void SetLength( BYTE *pb, ULONG cb ) const
  260. {
  261. Win4Assert( IsLengthStored() );
  262. * (ULONG *) (pb + GetLengthOffset() ) = cb;
  263. }
  264. void Marshall( PSerStream & stm, CPidMapper & pids ) const;
  265. void MarkAsSpecial() { _fSpecial = TRUE; }
  266. BOOL IsSpecial() { return _fSpecial; }
  267. inline void SetPartialDeferred( BOOL fPartialDeferred )
  268. {
  269. _fPartialDeferred = fPartialDeferred;
  270. }
  271. PROPID PropId; // Property ID
  272. private:
  273. USHORT _obValue; // offset in row data (for key if compressed)
  274. USHORT _cbValue; // width in row data (0 if compressed and no
  275. // key needed
  276. USHORT _obStatus; // offset in row data for value status (from
  277. // DBSTATUSENUM, but stored in 1 byte)
  278. USHORT _obLength; // offset in row data for value length (4 bytes)
  279. USHORT _usStoreParts; // from StoreParts enum
  280. VARTYPE _StoreAsType; // type stored in table
  281. VARTYPE _PredominantType;
  282. BOOL _fUniformType; // TRUE if all data are of type
  283. // _PredominantType
  284. BOOL _fGlobalCompr; // TRUE if _pCompression is a global compression
  285. BOOL _fSpecial; // TRUE if this property has special fetch/storage requirements
  286. CCompressedCol * _pCompression; // pointer to compressed col. data
  287. PROPID _CompressMasterID; // if !0, shared compression
  288. BOOL _fPartialDeferred; // TRUE if the column is partial deferred
  289. // (deferred till requested by client)
  290. BOOL _IsSpecialPathProcessing( CTableColumn const & dstCol ) const;
  291. BOOL _GetPathOrFile( CTableColumn const & dstCol, const BYTE * pbSrc,
  292. PVarAllocator & rDstPool, BYTE * pbDstRow );
  293. };
  294. //+-------------------------------------------------------------------------
  295. //
  296. // Classes: CColumnMasterArray
  297. // CTableColumnArray
  298. //
  299. // Purpose: Dynamic arrays of the classes above. These support
  300. // Add, Get and Size methods. The CColumnMasterArray
  301. // and CTableColumnArray are wrapped by set classes
  302. // which add Find and other methods.
  303. //
  304. // Notes: In-place dynamic arrays can only be used with types
  305. // which do not have destructors.
  306. //
  307. // Interface:
  308. //
  309. //--------------------------------------------------------------------------
  310. DECL_DYNARRAY( CColumnMasterArray, CColumnMasterDesc )
  311. DECL_DYNARRAY( CTableColumnArray, CTableColumn )
  312. //+-------------------------------------------------------------------------
  313. //
  314. // Class: CTableColumnSet
  315. //
  316. // Purpose: A set of table columns. A dynamic array of columns
  317. // with the addition of a Find method to lookup by PropID.
  318. //
  319. // Interface:
  320. //
  321. //--------------------------------------------------------------------------
  322. class CTableColumnSet: public CTableColumnArray
  323. {
  324. public:
  325. CTableColumnSet(int size = 0) :
  326. _cColumns(0),
  327. CTableColumnArray( size) {}
  328. CTableColumnSet( PDeSerStream & stm, CPidMapper & pids );
  329. unsigned Count(void) const {
  330. return _cColumns;
  331. }
  332. void SetCount(unsigned cCol) {
  333. _cColumns = cCol;
  334. }
  335. void Add(CTableColumn* pCol, unsigned iCol);
  336. void Add(XPtr<CTableColumn> & pCol, unsigned iCol);
  337. CTableColumn* Find(PROPID const propid, BOOL& rfFound) const;
  338. CTableColumn* Find(PROPID const propid) const;
  339. void Marshall( PSerStream & stm, CPidMapper & pids ) const;
  340. private:
  341. unsigned _cColumns;
  342. };
  343. inline
  344. CTableColumn *
  345. CTableColumnSet::Find(
  346. PROPID const PropId
  347. ) const
  348. {
  349. for (unsigned i=0; i<Count(); i++)
  350. {
  351. CTableColumn* pCol = GetItem( i );
  352. Win4Assert( 0 != pCol );
  353. if ( pCol->PropId == PropId )
  354. return pCol;
  355. }
  356. Win4Assert( !"propid not found" );
  357. return 0;
  358. }
  359. //+-------------------------------------------------------------------------
  360. //
  361. // Class: CColumnMasterSet
  362. //
  363. // Purpose: A set of master columns. Multiple instances of a
  364. // column with the same property ID are collapsed in
  365. // the set.
  366. //
  367. // Interface:
  368. //
  369. //--------------------------------------------------------------------------
  370. class CColumnMasterSet
  371. {
  372. public:
  373. CColumnMasterSet(const CColumnSet* const pOutCols);
  374. CColumnMasterSet(unsigned Size);
  375. //
  376. // Add an instance of a column description
  377. //
  378. CColumnMasterDesc* Add(XPtr<CColumnMasterDesc> & xpNewItem);
  379. CColumnMasterDesc* Add(CColumnMasterDesc const & rNewItem);
  380. //
  381. // Lookup a column by property ID. Returns NULL if not found.
  382. //
  383. CColumnMasterDesc* Find(const PROPID propid);
  384. //
  385. // Passthrough to CColumnMasterArray
  386. //
  387. inline unsigned Size(void) { return _iNextFree; }
  388. inline CColumnMasterDesc& Get(unsigned i) { return *_aMasterCol.Get(i); }
  389. inline BOOL HasUserProp() { return _fHasUserProp; }
  390. private:
  391. //
  392. // Lookup a column by property ID. Returns NULL if not found.
  393. //
  394. CColumnMasterDesc* Find(const PROPID propid, unsigned& riCol);
  395. unsigned _iNextFree; // index of next column to use
  396. CColumnMasterArray _aMasterCol; // The column descriptors
  397. BOOL _fHasUserProp; // TRUE if non-system (deferred) property in list
  398. };