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

361 lines
11 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995 - 2000.
//
// File: qryspec.hxx
//
// Contents: ICommandTree implementation for OFS file stores
//
// Classes: CQuerySpec
//
// History: 30 Jun 1995 AlanW Created
//
//----------------------------------------------------------------------------
#pragma once
#include <rowset.hxx>
#include <rstprop.hxx>
#include <oldquery.hxx>
#include <dberror.hxx>
#include <impiunk.hxx>
#include <srvprvdr.h> // IServiceProperties
#include <proputl.hxx>
#include <proprst.hxx>
#include <session.hxx>
class CColumnsInfo;
class CColumnSet;
//
// CRootQueryStatus::_dwStatus flags
//
enum COMMAND_STATUS_FLAG {
CMD_TEXT_SET = 0x00000001, // Command text was set
CMD_TEXT_PREPARED = 0x00000002, // Command is prepared
CMD_TEXT_TOTREE = 0x00000004, // Tells SetCommandTree not to delete the command text
CMD_TREE_BUILT = 0x00000008,
CMD_OWNS_TREE = 0x00000010, // fCopy was FALSE during SetCommandTree
CMD_COLINFO_NOTPREPARED = 0x00000020, // ColumnsInfo should return DB_E_NOTPREPARED
CMD_EXEC_RUNNING = 0x10000000, // Command is executing
};
//+---------------------------------------------------------------------------
//
// Class: CRootQuerySpec
//
// Purpose: Base query spec, implements OLE-DB command object
//
// History: 30 Jun 1995 AlanW Created
// 10-31-97 danleg ICommandText & ICommandPrepare added
//----------------------------------------------------------------------------
typedef BOOL (*PFNCHECKTREENODE) (const CDbCmdTreeNode * pNode );
class CRootQuerySpec : public ICommandText, public ICommandPrepare,
/* public ICommandTree, */ public ICommandProperties,
/* public ICommandValidate, */ public IQuery,
public IAccessor, public IConvertType,
public IServiceProperties
{
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(); }
//
// ICommand methods
//
STDMETHOD(Cancel) ( );
STDMETHOD(Execute) ( IUnknown * pUnkOuter,
REFIID riid,
DBPARAMS * pParams,
DBROWCOUNT * pcRowsAffected,
IUnknown * * ppRowset);
STDMETHOD(GetDBSession) ( REFIID riid,
IUnknown ** ppSession );
//
// ICommandText methods
//
STDMETHOD(GetCommandText) ( GUID * pguidDialect,
LPOLESTR * ppwszCommand );
STDMETHOD(SetCommandText) ( REFGUID rguidDialect,
LPCOLESTR pwszCommand );
//
// ICommandPrepare methods
//
STDMETHOD(Prepare) ( ULONG cExpectedRuns );
STDMETHOD(Unprepare) ( );
//
// ICommandTree methods
//
STDMETHOD(FindErrorNodes) ( const DBCOMMANDTREE* pRoot,
ULONG * pcErrorNodes,
DBCOMMANDTREE *** prgErrorNodes);
STDMETHOD(FreeCommandTree) ( DBCOMMANDTREE ** ppRoot );
STDMETHOD(GetCommandTree) ( DBCOMMANDTREE ** ppRoot );
STDMETHOD(SetCommandTree) ( DBCOMMANDTREE * * ppRoot,
DBCOMMANDREUSE dwCommandReuse,
BOOL fCopy);
#if 0
// ICommandValidate not yet implemented
//
// ICommandValidate methods
//
STDMETHOD(ValidateCompletely) ( );
STDMETHOD(ValidateSyntax) ( );
#endif // 0 // not implemented now.
//
// IQuery methods
//
STDMETHOD(AddPostProcessing) ( DBCOMMANDTREE * * ppRoot,
BOOL fCopy);
STDMETHOD(GetCardinalityEstimate) (
DBORDINAL * pulCardinality);
//
// ICommandProperties methods
//
STDMETHOD(GetProperties) ( const ULONG cPropertySetIDs,
const DBPROPIDSET rgPropertySetIDs[],
ULONG * pcPropertySets,
DBPROPSET ** prgPropertySets);
STDMETHOD(SetProperties) ( ULONG cPropertySets,
DBPROPSET rgPropertySets[]);
//
// 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);
//
// IConvertType methods
//
STDMETHOD(CanConvert) (DBTYPE wFromType,
DBTYPE wToType,
DBCONVERTFLAGS dwConvertFlags );
//
// IServiceProperties methods
//
STDMETHOD(GetPropertyInfo) ( ULONG cPropertyIDSets,
const DBPROPIDSET rgPropertyIDSets[ ],
ULONG *pcPropertyInfoSets,
DBPROPINFOSET **prgPropertyInfoSets,
OLECHAR **ppDescBuffer );
STDMETHOD(SetRequestedProperties) ( ULONG cPropertySets,
DBPROPSET rgPropertySets[ ] );
STDMETHOD(SetSuppliedProperties) ( ULONG cPropertySets,
DBPROPSET rgPropertySets[ ]);
//
// Non-interface public methods
//
inline BOOL IsRowsetOpen() { return (HaveQuery() && _pInternalQuery->IsQueryActive()); }
//
// Build a Query Tree from SQL text
//
SCODE BuildTree( );
inline BOOL IsCommandSet() { return (_dwStatus & CMD_TEXT_SET); }
inline void ImpersonateOpenRowset() { _fGenByOpenRowset = TRUE; }
inline BOOL IsGenByOpenRowset() { return _fGenByOpenRowset; }
inline static BOOL IsValidFromVariantType( DBTYPE wTypeIn )
{
DBTYPE wType = wTypeIn & VT_TYPEMASK;
return (! ((wType > VT_DECIMAL && wType < VT_I1) ||
(wType > VT_LPWSTR && wType < VT_FILETIME && wType != VT_RECORD) ||
(wType > VT_CLSID)) );
}
inline static BOOL IsVariableLengthType( DBTYPE wTypeIn )
{
DBTYPE wType = wTypeIn & VT_TYPEMASK;
return wType == DBTYPE_STR ||
wType == DBTYPE_BYTES ||
wType == DBTYPE_WSTR ||
wType == DBTYPE_VARNUMERIC;
}
protected:
//
// Ctor / Dtor
//
CRootQuerySpec (IUnknown * pUnkOuter, IUnknown ** ppMyUnk, CDBSession * pSession=0);
CRootQuerySpec ( CRootQuerySpec & src );
virtual ~CRootQuerySpec ();
SCODE RealQueryInterface( REFIID ifid, void * *ppiuk ); // used by _pControllingUnknown
// in aggregation - does QI without delegating to outer unknown
//
// Scope access.
//
void SetDepth( DWORD dwDepth ) { _dwDepth = dwDepth; }
DWORD Depth() { return _dwDepth; }
virtual PIInternalQuery * QueryInternalQuery() = 0;
void ReleaseInternalQuery()
{
if ( 0 != _pInternalQuery )
{
_pInternalQuery->Release();
_pInternalQuery = 0;
}
}
//
// Syncronize access to the command object
//
CMutexSem _mtxCmd;
//
// Support Ole DB error handling
//
CCIOleDBError _DBErrorObj;
//
// Execution status flags
//
ULONG _dwStatus;
//
// Current SQL text, if any
//
WCHAR* _pwszSQLText;
//
// GUID for dialect of current text or tree
//
GUID _guidCmdDialect;
//
// Session that created this command, if any
//
XInterface<CDBSession> _xSession;
XInterface<IParserSession> _xpIPSession;
BOOL _fGenByOpenRowset;
private:
void CreateParser();
void _FindTreeNodes( const CDbCmdTreeNode * pRoot,
ULONG & rcMatchingNodes,
XArrayOLE<DBCOMMANDTREE *> & rpMatchingNodes,
PFNCHECKTREENODE pfnCheck,
unsigned iDepth = 0);
void _CheckRootNode( const DBCOMMANDTREE* pRoot);
BOOL HaveQuery() { return ( 0 != _pInternalQuery ); }
CColumnsInfo * GetColumnsInfo();
void InitColumns( );
DWORD _dwDepth; // query depth
PIInternalQuery * _pInternalQuery; // PIInternalQuery to create rowsets
CDbCmdTreeNode * _pQueryTree; // the query tree
//
// For implementing ICommandProperties
//
CMRowsetProps _RowsetProps;
//
// IServiceProperties::GetPropertyInfo
//
CMDSPropInfo _PropInfo;
//
// For implementing IColumnsInfo
//
CColumnsInfo * _pColumnsInfo; // implements IColumnsInfo
//
// Keeps track of accessors handed out by this object.
//
CAccessorBag _aAccessors;
IUnknown * _pControllingUnknown; // outer unknown
friend class CImpIUnknown<CRootQuerySpec>;
CImpIUnknown<CRootQuerySpec> _impIUnknown;
XInterface<IParser> _xIParser;
//
// Default catalog.
//
XArray<WCHAR> _xpwszCatalog;
};