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.

360 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 2000.
  5. //
  6. // File: qryspec.hxx
  7. //
  8. // Contents: ICommandTree implementation for OFS file stores
  9. //
  10. // Classes: CQuerySpec
  11. //
  12. // History: 30 Jun 1995 AlanW Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include <rowset.hxx>
  17. #include <rstprop.hxx>
  18. #include <oldquery.hxx>
  19. #include <dberror.hxx>
  20. #include <impiunk.hxx>
  21. #include <srvprvdr.h> // IServiceProperties
  22. #include <proputl.hxx>
  23. #include <proprst.hxx>
  24. #include <session.hxx>
  25. class CColumnsInfo;
  26. class CColumnSet;
  27. //
  28. // CRootQueryStatus::_dwStatus flags
  29. //
  30. enum COMMAND_STATUS_FLAG {
  31. CMD_TEXT_SET = 0x00000001, // Command text was set
  32. CMD_TEXT_PREPARED = 0x00000002, // Command is prepared
  33. CMD_TEXT_TOTREE = 0x00000004, // Tells SetCommandTree not to delete the command text
  34. CMD_TREE_BUILT = 0x00000008,
  35. CMD_OWNS_TREE = 0x00000010, // fCopy was FALSE during SetCommandTree
  36. CMD_COLINFO_NOTPREPARED = 0x00000020, // ColumnsInfo should return DB_E_NOTPREPARED
  37. CMD_EXEC_RUNNING = 0x10000000, // Command is executing
  38. };
  39. //+---------------------------------------------------------------------------
  40. //
  41. // Class: CRootQuerySpec
  42. //
  43. // Purpose: Base query spec, implements OLE-DB command object
  44. //
  45. // History: 30 Jun 1995 AlanW Created
  46. // 10-31-97 danleg ICommandText & ICommandPrepare added
  47. //----------------------------------------------------------------------------
  48. typedef BOOL (*PFNCHECKTREENODE) (const CDbCmdTreeNode * pNode );
  49. class CRootQuerySpec : public ICommandText, public ICommandPrepare,
  50. /* public ICommandTree, */ public ICommandProperties,
  51. /* public ICommandValidate, */ public IQuery,
  52. public IAccessor, public IConvertType,
  53. public IServiceProperties
  54. {
  55. public:
  56. //
  57. // IUnknown methods.
  58. //
  59. STDMETHOD(QueryInterface) ( THIS_ REFIID riid,
  60. LPVOID *ppiuk )
  61. {
  62. return _pControllingUnknown->QueryInterface(riid,ppiuk);
  63. }
  64. STDMETHOD_(ULONG, AddRef) (THIS) { return _pControllingUnknown->AddRef(); }
  65. STDMETHOD_(ULONG, Release) (THIS) {return _pControllingUnknown->Release(); }
  66. //
  67. // ICommand methods
  68. //
  69. STDMETHOD(Cancel) ( );
  70. STDMETHOD(Execute) ( IUnknown * pUnkOuter,
  71. REFIID riid,
  72. DBPARAMS * pParams,
  73. DBROWCOUNT * pcRowsAffected,
  74. IUnknown * * ppRowset);
  75. STDMETHOD(GetDBSession) ( REFIID riid,
  76. IUnknown ** ppSession );
  77. //
  78. // ICommandText methods
  79. //
  80. STDMETHOD(GetCommandText) ( GUID * pguidDialect,
  81. LPOLESTR * ppwszCommand );
  82. STDMETHOD(SetCommandText) ( REFGUID rguidDialect,
  83. LPCOLESTR pwszCommand );
  84. //
  85. // ICommandPrepare methods
  86. //
  87. STDMETHOD(Prepare) ( ULONG cExpectedRuns );
  88. STDMETHOD(Unprepare) ( );
  89. //
  90. // ICommandTree methods
  91. //
  92. STDMETHOD(FindErrorNodes) ( const DBCOMMANDTREE* pRoot,
  93. ULONG * pcErrorNodes,
  94. DBCOMMANDTREE *** prgErrorNodes);
  95. STDMETHOD(FreeCommandTree) ( DBCOMMANDTREE ** ppRoot );
  96. STDMETHOD(GetCommandTree) ( DBCOMMANDTREE ** ppRoot );
  97. STDMETHOD(SetCommandTree) ( DBCOMMANDTREE * * ppRoot,
  98. DBCOMMANDREUSE dwCommandReuse,
  99. BOOL fCopy);
  100. #if 0
  101. // ICommandValidate not yet implemented
  102. //
  103. // ICommandValidate methods
  104. //
  105. STDMETHOD(ValidateCompletely) ( );
  106. STDMETHOD(ValidateSyntax) ( );
  107. #endif // 0 // not implemented now.
  108. //
  109. // IQuery methods
  110. //
  111. STDMETHOD(AddPostProcessing) ( DBCOMMANDTREE * * ppRoot,
  112. BOOL fCopy);
  113. STDMETHOD(GetCardinalityEstimate) (
  114. DBORDINAL * pulCardinality);
  115. //
  116. // ICommandProperties methods
  117. //
  118. STDMETHOD(GetProperties) ( const ULONG cPropertySetIDs,
  119. const DBPROPIDSET rgPropertySetIDs[],
  120. ULONG * pcPropertySets,
  121. DBPROPSET ** prgPropertySets);
  122. STDMETHOD(SetProperties) ( ULONG cPropertySets,
  123. DBPROPSET rgPropertySets[]);
  124. //
  125. // IAccessor methods
  126. //
  127. STDMETHOD(AddRefAccessor) (HACCESSOR hAccessor,
  128. ULONG * pcRefCount);
  129. STDMETHOD(CreateAccessor) (DBACCESSORFLAGS dwBindIO,
  130. DBCOUNTITEM cBindings,
  131. const DBBINDING rgBindings[],
  132. DBLENGTH cbRowSize,
  133. HACCESSOR * phAccessor,
  134. DBBINDSTATUS rgStatus[]);
  135. STDMETHOD(GetBindings) (HACCESSOR hAccessor,
  136. DBACCESSORFLAGS * pdwBindIO,
  137. DBCOUNTITEM * pcBindings,
  138. DBBINDING * * prgBindings) /*const*/;
  139. STDMETHOD(ReleaseAccessor) (HACCESSOR hAccessor,
  140. ULONG * pcRefCount);
  141. //
  142. // IConvertType methods
  143. //
  144. STDMETHOD(CanConvert) (DBTYPE wFromType,
  145. DBTYPE wToType,
  146. DBCONVERTFLAGS dwConvertFlags );
  147. //
  148. // IServiceProperties methods
  149. //
  150. STDMETHOD(GetPropertyInfo) ( ULONG cPropertyIDSets,
  151. const DBPROPIDSET rgPropertyIDSets[ ],
  152. ULONG *pcPropertyInfoSets,
  153. DBPROPINFOSET **prgPropertyInfoSets,
  154. OLECHAR **ppDescBuffer );
  155. STDMETHOD(SetRequestedProperties) ( ULONG cPropertySets,
  156. DBPROPSET rgPropertySets[ ] );
  157. STDMETHOD(SetSuppliedProperties) ( ULONG cPropertySets,
  158. DBPROPSET rgPropertySets[ ]);
  159. //
  160. // Non-interface public methods
  161. //
  162. inline BOOL IsRowsetOpen() { return (HaveQuery() && _pInternalQuery->IsQueryActive()); }
  163. //
  164. // Build a Query Tree from SQL text
  165. //
  166. SCODE BuildTree( );
  167. inline BOOL IsCommandSet() { return (_dwStatus & CMD_TEXT_SET); }
  168. inline void ImpersonateOpenRowset() { _fGenByOpenRowset = TRUE; }
  169. inline BOOL IsGenByOpenRowset() { return _fGenByOpenRowset; }
  170. inline static BOOL IsValidFromVariantType( DBTYPE wTypeIn )
  171. {
  172. DBTYPE wType = wTypeIn & VT_TYPEMASK;
  173. return (! ((wType > VT_DECIMAL && wType < VT_I1) ||
  174. (wType > VT_LPWSTR && wType < VT_FILETIME && wType != VT_RECORD) ||
  175. (wType > VT_CLSID)) );
  176. }
  177. inline static BOOL IsVariableLengthType( DBTYPE wTypeIn )
  178. {
  179. DBTYPE wType = wTypeIn & VT_TYPEMASK;
  180. return wType == DBTYPE_STR ||
  181. wType == DBTYPE_BYTES ||
  182. wType == DBTYPE_WSTR ||
  183. wType == DBTYPE_VARNUMERIC;
  184. }
  185. protected:
  186. //
  187. // Ctor / Dtor
  188. //
  189. CRootQuerySpec (IUnknown * pUnkOuter, IUnknown ** ppMyUnk, CDBSession * pSession=0);
  190. CRootQuerySpec ( CRootQuerySpec & src );
  191. virtual ~CRootQuerySpec ();
  192. SCODE RealQueryInterface( REFIID ifid, void * *ppiuk ); // used by _pControllingUnknown
  193. // in aggregation - does QI without delegating to outer unknown
  194. //
  195. // Scope access.
  196. //
  197. void SetDepth( DWORD dwDepth ) { _dwDepth = dwDepth; }
  198. DWORD Depth() { return _dwDepth; }
  199. virtual PIInternalQuery * QueryInternalQuery() = 0;
  200. void ReleaseInternalQuery()
  201. {
  202. if ( 0 != _pInternalQuery )
  203. {
  204. _pInternalQuery->Release();
  205. _pInternalQuery = 0;
  206. }
  207. }
  208. //
  209. // Syncronize access to the command object
  210. //
  211. CMutexSem _mtxCmd;
  212. //
  213. // Support Ole DB error handling
  214. //
  215. CCIOleDBError _DBErrorObj;
  216. //
  217. // Execution status flags
  218. //
  219. ULONG _dwStatus;
  220. //
  221. // Current SQL text, if any
  222. //
  223. WCHAR* _pwszSQLText;
  224. //
  225. // GUID for dialect of current text or tree
  226. //
  227. GUID _guidCmdDialect;
  228. //
  229. // Session that created this command, if any
  230. //
  231. XInterface<CDBSession> _xSession;
  232. XInterface<IParserSession> _xpIPSession;
  233. BOOL _fGenByOpenRowset;
  234. private:
  235. void CreateParser();
  236. void _FindTreeNodes( const CDbCmdTreeNode * pRoot,
  237. ULONG & rcMatchingNodes,
  238. XArrayOLE<DBCOMMANDTREE *> & rpMatchingNodes,
  239. PFNCHECKTREENODE pfnCheck,
  240. unsigned iDepth = 0);
  241. void _CheckRootNode( const DBCOMMANDTREE* pRoot);
  242. BOOL HaveQuery() { return ( 0 != _pInternalQuery ); }
  243. CColumnsInfo * GetColumnsInfo();
  244. void InitColumns( );
  245. DWORD _dwDepth; // query depth
  246. PIInternalQuery * _pInternalQuery; // PIInternalQuery to create rowsets
  247. CDbCmdTreeNode * _pQueryTree; // the query tree
  248. //
  249. // For implementing ICommandProperties
  250. //
  251. CMRowsetProps _RowsetProps;
  252. //
  253. // IServiceProperties::GetPropertyInfo
  254. //
  255. CMDSPropInfo _PropInfo;
  256. //
  257. // For implementing IColumnsInfo
  258. //
  259. CColumnsInfo * _pColumnsInfo; // implements IColumnsInfo
  260. //
  261. // Keeps track of accessors handed out by this object.
  262. //
  263. CAccessorBag _aAccessors;
  264. IUnknown * _pControllingUnknown; // outer unknown
  265. friend class CImpIUnknown<CRootQuerySpec>;
  266. CImpIUnknown<CRootQuerySpec> _impIUnknown;
  267. XInterface<IParser> _xIParser;
  268. //
  269. // Default catalog.
  270. //
  271. XArray<WCHAR> _xpwszCatalog;
  272. };