595 lines
14 KiB
C++
595 lines
14 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright 1995-2000 Microsoft Corporation.
|
|
//
|
|
// @doc
|
|
//
|
|
// @module CTree Header Module | This module contains header information for CTree
|
|
//
|
|
// @comm
|
|
// Special Notes...: (OPTIONAL NOTES FOR SPECIAL CIRCUMSTANCES)
|
|
//
|
|
// <nl><nl>
|
|
// Revision History:<nl>
|
|
//---------------------------------------------------------------------------
|
|
|
|
#ifndef _CTree_HPP_
|
|
#define _CTree_HPP_
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Includes
|
|
//
|
|
/////////////////////////////////////////////////////////////////////
|
|
#include "List.h"
|
|
|
|
|
|
typedef enum
|
|
{
|
|
NC_NONE = 0x0,
|
|
NC_Collection = 0x1,
|
|
NC_Singleton = 0x2,
|
|
NC_LEAF = 0x4,
|
|
NC_SUBTREE = 0x8,
|
|
NC_LEAF_Collection = NC_LEAF | NC_Collection,
|
|
} NODE_CONSTRAINT;
|
|
|
|
typedef enum
|
|
{
|
|
PCO_NONE = 0x0,
|
|
PCO_DIFF = 0x1,
|
|
PCO_OVERLAP = 0x2,
|
|
} PAIR_CONSTRAINT;
|
|
|
|
typedef BOOL (*CColApplicator)(CCol*);
|
|
|
|
class CSchema
|
|
{
|
|
private:
|
|
|
|
// row URL (the row on whose children rowset is opened)
|
|
WCHAR * m_pwszRowURL;
|
|
// the last part of the URL (name relative to parent)
|
|
WCHAR * m_pwszRowName;
|
|
|
|
// parent row seed; equals to -1 if not used => seed values limited to
|
|
// half of MAX_PTR
|
|
// for an ini file this value should be the row number
|
|
LONG_PTR m_lSeed;
|
|
|
|
// Number of leaves this schema has
|
|
ULONG_PTR m_cLeaves;
|
|
|
|
// info about the row being collection or not
|
|
BOOL m_fIsCollection;
|
|
|
|
protected:
|
|
// Indicates if NULL values will be generated by MakeData.
|
|
ENULL m_eNull;
|
|
|
|
// Column which has index on it. <nl>
|
|
DBORDINAL m_ulIndex;
|
|
|
|
// Column which has primary key constraint on it. <nl>
|
|
DBORDINAL m_ulPrimaryKey;
|
|
|
|
// @cmember Indicates if Primary Key will be created on a table
|
|
ECREATE_PK m_eCreatePK;
|
|
|
|
// List of columns in this schema. <nl>
|
|
CList <CCol,CCol&> m_ColList;
|
|
|
|
// List of descendents of this row. <nl>
|
|
CList <CSchema*,CSchema*> m_ChildrenList;
|
|
|
|
// the parent CSchema
|
|
CSchema * m_pParentSchema;
|
|
|
|
// Count of supported variant subtypes
|
|
ULONG m_cVariantSubTypes;
|
|
|
|
// Array of variant subtypes
|
|
DBTYPE m_rgVariantSubTypes[MAX_VARIANT_SUBTYPES];
|
|
|
|
// Updates CCol List based on information found in rgData. rgData
|
|
// an entire row.
|
|
HRESULT UpdateCCol
|
|
(
|
|
DBCOUNTITEM cBindings,
|
|
DBBINDING * rgBindings,
|
|
void * pData,
|
|
CCol & NewCol, // [IN/OUT] Element from the CCol List
|
|
EDATATYPES eDataTypes, // [IN] Enum for column data type
|
|
ULONG * pulAutoIncPrec, // [IN/OUT] Precision of largest autoincrement column
|
|
LONG_PTR lSQLSupport // [IN] SQL Support Level
|
|
);
|
|
|
|
public:
|
|
|
|
// used to speed up node retrieval
|
|
// when moving to the next node in a tree, based on a CSchema ptr
|
|
// (the crt position), one will get the parent CSchema and
|
|
// try to move child (m_ulCacheSelection+1)
|
|
LONG_PTR m_lCacheSelection;
|
|
|
|
CSchema
|
|
(
|
|
CSchema * pParentSchema = NULL, // [in] the parent schema of the row
|
|
WCHAR * pwszParentRowURL = NULL,// [in] the URL of the parent row
|
|
LONG_PTR lSeed = -1, // [in] the seed value used for the row
|
|
ENULL eNull = USENULLS, // [in] tells if nulls are used
|
|
ECREATE_PK eCreatePK=CREATENEVER_PK // [in] tells if a primary key be created
|
|
);
|
|
|
|
CSchema::CSchema
|
|
(
|
|
CSchema * pSchema, // [in] the schema to be copied
|
|
CSchema * pParentSchema = NULL, // [in] the parent schema (if exists)
|
|
BOOL fNonRecursive = FALSE // [in] whether the copying is recursive or not
|
|
);
|
|
|
|
virtual ~CSchema(void);
|
|
|
|
void SetParentSchema(CSchema *pSchema)
|
|
{
|
|
m_pParentSchema = pSchema;
|
|
}
|
|
|
|
CSchema *GetParentSchema()
|
|
{
|
|
return m_pParentSchema;
|
|
}
|
|
|
|
// manipulate the list of children
|
|
void AddChild(CSchema *pSchema);
|
|
void RemoveChild(CSchema *pSchema);
|
|
|
|
virtual HRESULT InitSchema(IUnknown* pIUnknown);
|
|
|
|
virtual HRESULT SetFromColumnsInfo
|
|
(
|
|
IColumnsInfo * pIColumnsInfo,
|
|
DBORDINAL * pcColsColInfo
|
|
);
|
|
|
|
virtual HRESULT SetFromColumnsRowset
|
|
(
|
|
IColumnsRowset * pIColumnsRowset,
|
|
DBORDINAL * pcColsFound
|
|
);
|
|
|
|
// retrieve the column list (for the copy constructor)
|
|
CList <CCol,CCol&> *GetColList()
|
|
{
|
|
return &m_ColList;
|
|
}
|
|
|
|
// retrieve the children list (for the copy constructor)
|
|
CList <CSchema*,CSchema*> *GetChildrenList()
|
|
{
|
|
return &m_ChildrenList;
|
|
}
|
|
|
|
// @cmember Gets CCol object associated with criteria
|
|
virtual HRESULT GetColInfo
|
|
(
|
|
CColApplicator pfApp, // [IN] Accepting criteria
|
|
CCol & ColInfo // [OUT] CCol object
|
|
);
|
|
|
|
// @cmember Gets CCol object associated with column number.
|
|
virtual HRESULT GetColInfo
|
|
(
|
|
DBORDINAL ulColNum, // [IN] Column number
|
|
CCol & ColInfo // [OUT] CCol object
|
|
);
|
|
|
|
// @cmember Gets first CCol object associated with Provider type.
|
|
virtual HRESULT GetColInfo
|
|
(
|
|
CCol & col, // [OUT] CCol object
|
|
DBTYPE wType // [IN] Datatype
|
|
);
|
|
|
|
// @cmember Gets first CCol object associated with Provider type.
|
|
virtual HRESULT GetColInfo
|
|
(
|
|
CCol & col, // [OUT] CCol object
|
|
WCHAR *pwszTypeName // [IN] Provider typename
|
|
);
|
|
|
|
// @cmember Gets first CCol object associated with dbcid (ColumnID).
|
|
virtual HRESULT GetColInfo
|
|
(
|
|
DBID * dbcid, // [IN] Column ID to be retrieved
|
|
CCol & col // [OUT] CCol object
|
|
);
|
|
|
|
// @cmember Returns CCol object associated with column number
|
|
virtual CCol & GetColInfoForUpdate
|
|
(
|
|
DBORDINAL ulColNum // [IN] Column number searching for, 1 based
|
|
);
|
|
|
|
LONG_PTR GetSeed()
|
|
{
|
|
return m_lSeed;
|
|
}
|
|
|
|
// @cmember returns info about the row being collection or not
|
|
BOOL IsCollection()
|
|
{
|
|
return m_fIsCollection;
|
|
}
|
|
|
|
virtual HRESULT MakeData
|
|
(
|
|
WCHAR * wszData, // @parm [OUT] Return data
|
|
DBCOUNTITEM ulRowNum, // @parm [IN] Row number which is one based
|
|
DBORDINAL iOrdinal, // @parm [IN] Column number which is one based
|
|
EVALUE eValue, // @parm [IN] Primary or secondary data
|
|
DBTYPE wSubType=DBTYPE_EMPTY, // @parm [IN] Column SubType
|
|
BOOL bNoNullValues=FALSE, // [IN] if bNoNullValues is True then MakeData will return valid data.
|
|
DBTYPE * pwVariantType=NULL // [OUT] Optional, returns underlying type if backend is a Variant
|
|
);
|
|
|
|
// Returns client's request to use nulls or not use nulls.
|
|
inline ENULL GetNull(void)
|
|
{
|
|
return m_eNull;
|
|
}
|
|
|
|
// Returns client's request to use nulls or not use nulls.
|
|
inline void SetNull(ENULL eNull)
|
|
{
|
|
m_eNull = eNull;
|
|
}
|
|
|
|
// Return Column number which index is created on.
|
|
inline DBORDINAL GetIndexColumn(void)
|
|
{
|
|
return m_ulIndex;
|
|
}
|
|
|
|
// Set Column number which index is created on.
|
|
inline DBORDINAL SetIndexColumn(DBORDINAL ulIndex)
|
|
{
|
|
DBORDINAL ulOldIndex = m_ulIndex;
|
|
|
|
m_ulIndex=ulIndex;
|
|
return ulOldIndex;
|
|
}
|
|
|
|
// Returns Column number which primary key is created on.
|
|
inline DBORDINAL GetPrimaryKeyColumn(void) {return m_ulPrimaryKey;}
|
|
|
|
// Sets Column number which Primary key is created on.
|
|
// Note!!!: if m_eCreatePK==CREATENEVER_PK then m_ulPrimaryKey will be ignored
|
|
inline void SetPrimaryKeyColumn(DBORDINAL ulPrimaryKey) {m_ulPrimaryKey=ulPrimaryKey;}
|
|
|
|
// Returns m_eCreatePK
|
|
inline ECREATE_PK GetCreatePK(void) {return m_eCreatePK;}
|
|
|
|
// Sets m_eCreatePK
|
|
void SetCreatePK(ECREATE_PK eCreatePK)
|
|
{
|
|
m_eCreatePK=eCreatePK;
|
|
if (CREATENEVER_PK==eCreatePK)
|
|
m_ulPrimaryKey=0;
|
|
}
|
|
|
|
DBCOUNTITEM SetLeafNo(DBCOUNTITEM cLeaves)
|
|
{
|
|
return m_cLeaves = cLeaves;
|
|
}
|
|
|
|
LONG_PTR SetSeed(LONG_PTR lSeed)
|
|
{
|
|
return m_lSeed = lSeed;
|
|
}
|
|
|
|
DBCOUNTITEM GetLeafNo(void)
|
|
{
|
|
return m_cLeaves;
|
|
}
|
|
|
|
DBCOUNTITEM GetChildrenNo(void)
|
|
{
|
|
return m_ChildrenList.GetCount();
|
|
}
|
|
|
|
// returns the URL associated with this row
|
|
WCHAR * GetRowURL()
|
|
{
|
|
return m_pwszRowURL;
|
|
}
|
|
|
|
// returns the last part of the name (e.g. confprov://dso/session/t/1/2/3 => 3)
|
|
WCHAR * GetRowName()
|
|
{
|
|
return m_pwszRowName;
|
|
}
|
|
|
|
WCHAR * SetRowURL
|
|
(
|
|
WCHAR *pwszRowURL
|
|
);
|
|
|
|
// methods to retrieve one of the children
|
|
CSchema * GetChild
|
|
(
|
|
DBCOUNTITEM ulIndex
|
|
);
|
|
|
|
CSchema * GetChild
|
|
(
|
|
WCHAR * pwszName,
|
|
DBCOUNTITEM * pulIndex = NULL
|
|
);
|
|
|
|
// method to update the URL of the tree
|
|
void UpdateURL(WCHAR *pwszURL);
|
|
|
|
// returns the index of the child given in the children list
|
|
LONG_PTR GetChildIndex(CSchema *pSchema);
|
|
|
|
// Populates an col list with a Provider's type information
|
|
HRESULT CSchema::PopulateTypeInfo
|
|
(
|
|
IUnknown * pIUnknown,
|
|
LONG_PTR lSQLSupport
|
|
);
|
|
|
|
// Returns the number of columns in the schema list
|
|
inline DBORDINAL CountColumnsOnSchema(void)
|
|
{
|
|
return (DBORDINAL) m_ColList.GetCount();
|
|
};
|
|
|
|
inline void GetVariantSubTypes(ULONG * pcVariantSubTypes, DBTYPE ** pprgVariantSubTypes)
|
|
{
|
|
ASSERT(pcVariantSubTypes && pprgVariantSubTypes);
|
|
|
|
*pcVariantSubTypes = m_cVariantSubTypes;
|
|
*pprgVariantSubTypes = m_rgVariantSubTypes;
|
|
}
|
|
};
|
|
|
|
|
|
class CTree
|
|
{
|
|
protected:
|
|
|
|
// A Tree to CSchema objects
|
|
CSchema * m_pRootSchema;
|
|
CSchema * m_pCrtSchema;
|
|
// Iteration limit
|
|
// This is the level of the subtree root.
|
|
// SetPosition sets this value and ResetPosition resets it to 0.
|
|
// When the iteration returns to this level in the tree, nav will stop.
|
|
CSchema * m_pStartingSchema;
|
|
|
|
|
|
// The depth that the tree was created with
|
|
DBCOUNTITEM m_ulMaxDepth;
|
|
|
|
// Number of children per node when tree was created
|
|
DBCOUNTITEM m_cMaxChildrenPerNode;
|
|
|
|
// Root Node
|
|
WCHAR * m_pwszTreeRoot;
|
|
|
|
// RootBinder interfaces
|
|
IBindResource * m_pIBindResource;
|
|
ICreateRow * m_pICreateRow;
|
|
|
|
// store the value of DBPROP_GENERATEURL property
|
|
LONG_PTR m_lGenerateURL;
|
|
|
|
public:
|
|
|
|
CTree
|
|
(
|
|
IUnknown * pSessionIUnknown, // [IN] SessionInterface
|
|
WCHAR * pwszModuleName=NULL, // [IN] Tree name, optional (Default=NULL)
|
|
ENULL eNull=USENULLS // [IN] Should nulls be used (Default=USENULLS)
|
|
);
|
|
|
|
virtual ~CTree(void);
|
|
|
|
virtual HRESULT CreateTree
|
|
(
|
|
WCHAR * pwszRootURL,
|
|
DBCOUNTITEM ulDepth,
|
|
DBCOUNTITEM cMaxChildrenPerNode
|
|
);
|
|
|
|
virtual HRESULT CopyTree
|
|
(
|
|
CTree * pCTree, // [in] the tree to be copied
|
|
WCHAR * pwszBaseRootURL // [in] the base root URL where to copy the tree
|
|
);
|
|
|
|
virtual HRESULT CreateAndPopulateRow
|
|
(
|
|
CSchema * pParentSchema, // [in] parent node's schema
|
|
ULONG_PTR ulSeed, // [in] the seed of the row
|
|
WCHAR * pwszURL, // [in] row URL
|
|
DBBINDURLFLAG dwBindURLFlags, // [in] binding flags
|
|
CSchema ** ppSchema, // [out] new row's schema
|
|
IUnknown ** ppIRowChange, // [out] pointer to interface to be returned
|
|
WCHAR ** ppwszNewURL // [out] pointer to the name of the new row
|
|
);
|
|
|
|
// check the rowset opened on pwszParentURL
|
|
// making sure that all the rows expected are contained and their values are ok
|
|
BOOL CheckRowset
|
|
(
|
|
IRowset * pIRowset, // [in] interface on the checked rowset
|
|
WCHAR * pwszParentURL, // [in] the URL used to open the rowset
|
|
BOOL fCmpRowVal = TRUE // [in] whether or not to compare the row values
|
|
);
|
|
|
|
BOOL CheckRowset
|
|
(
|
|
IRowset * pIRowset, // [in] interface on the checked rowset
|
|
CSchema * pRowsetSchema, // [in] schema of the rowset to be checked
|
|
BOOL fCmpRowVal // [in] whether or not to compare the row values
|
|
);
|
|
|
|
// checks whether all the rows in the tree can be bound
|
|
BOOL CheckTreeStructure();
|
|
|
|
// checks the tree structure as well as the values
|
|
BOOL CheckTree();
|
|
|
|
virtual HRESULT CreateChildRowset
|
|
(
|
|
CSchema * pParentSchema,
|
|
WCHAR * pwszParentURL,
|
|
DBCOUNTITEM cChildren,
|
|
DBCOUNTITEM ulDepth,
|
|
ULONG_PTR ulParentSeed = 1
|
|
);
|
|
|
|
virtual HRESULT DestroyTree();
|
|
|
|
virtual CSchema * GetSchema(WCHAR *pwszURL);
|
|
|
|
DBCOUNTITEM GetMaxDepth()
|
|
{
|
|
return m_ulMaxDepth;
|
|
}
|
|
|
|
DBCOUNTITEM GetMaxChildrenPerNode()
|
|
{
|
|
return m_cMaxChildrenPerNode;
|
|
}
|
|
|
|
virtual CSchema * GetCurrentSchema();
|
|
|
|
virtual WCHAR * GetCurrentRowURL();
|
|
|
|
virtual CSchema* GetRootSchema();
|
|
|
|
virtual HRESULT GetRelativeRowURL
|
|
(
|
|
WCHAR * pwszAbsoluteRowURL, // [in]
|
|
WCHAR ** ppwszRelativeRowURL // [out]
|
|
);
|
|
|
|
virtual HRESULT GetAbsoluteRowURL
|
|
(
|
|
WCHAR * pwszRelativeRowURL, // [in]
|
|
WCHAR ** ppwszAbsoluteRowURL // [out]
|
|
);
|
|
|
|
HRESULT GetOuterCollection
|
|
(
|
|
WCHAR * pwszLeafURL, // [in] the URL of the leaf row
|
|
WCHAR ** ppwszOuterCollection // [out] the URL of the outest Collection in the given path
|
|
);
|
|
|
|
HRESULT GetCommonAncestor
|
|
(
|
|
WCHAR * pwszFirstURL, // [in] the first URL
|
|
WCHAR * pwszSecondURL, // [in] the second URL
|
|
WCHAR ** ppwszCommonURL // [out] the URL of closest common ancestor
|
|
);
|
|
|
|
virtual BOOL MakeSuffix
|
|
(
|
|
DBCOUNTITEM ulNode,
|
|
WCHAR * pwszBaseURL,
|
|
WCHAR ** ppwszNewURL
|
|
);
|
|
|
|
virtual BOOL MakeSuffix
|
|
(
|
|
WCHAR * pwszNode,
|
|
WCHAR * pwszBaseURL,
|
|
WCHAR ** ppwszNewURL
|
|
);
|
|
|
|
virtual CSchema* AddSchema
|
|
(
|
|
CSchema * pParentSchema, // [in] pointer to the parent schema
|
|
IRowset * pIParentRow, // [in] interface to the current row
|
|
WCHAR * pwszParentURL, // [in] row URL of the parent
|
|
LONG_PTR lSeed // [in] the seed value
|
|
);
|
|
|
|
WCHAR * GetRootURL()
|
|
{
|
|
return m_pwszTreeRoot;
|
|
}
|
|
|
|
HRESULT GetRowLevel
|
|
(
|
|
WCHAR * pwszURL, // [in] the URL of the chosen row
|
|
DBCOUNTITEM * pulLevel // [out] the level of the row in the hierarchy
|
|
);
|
|
|
|
LONG_PTR GetGenerateURL()
|
|
{
|
|
return m_lGenerateURL;
|
|
}
|
|
|
|
// setting exact position inside a tree
|
|
inline void ResetPosition()
|
|
{
|
|
m_pCrtSchema = m_pRootSchema;
|
|
m_pStartingSchema = m_pRootSchema;
|
|
}
|
|
|
|
HRESULT SetPosition(WCHAR *pwszURL);
|
|
|
|
void MoveDownToChildNode(DBCOUNTITEM ulChildOrdinal);
|
|
|
|
// move to the next sibling (if there is any)
|
|
HRESULT MoveToNextSibling();
|
|
|
|
// move to the next node
|
|
// this should set the position and return the URL of that node
|
|
HRESULT MoveToNextNode
|
|
(
|
|
WCHAR ** ppwszURL // [out] the URL of the node
|
|
);
|
|
|
|
void ReturnFromChildNode();
|
|
|
|
HRESULT GetRow
|
|
(
|
|
DBCOUNTITEM ulRow, // [in] the number of row (as a leaf)
|
|
WCHAR ** ppwszURL //[out] the URL of the chosen row
|
|
);
|
|
|
|
// get the number of the first leaf in the subtree
|
|
// starting at the current position
|
|
DBCOUNTITEM GetNoOfFirstLeafInSubtree(CSchema*);
|
|
|
|
// @cmember tests whether the row give by its URL is a collection
|
|
BOOL IsCollection(WCHAR*);
|
|
BOOL IsCollection(CSchema *pSchema);
|
|
|
|
// methods that check the column values of a row
|
|
HRESULT VerifyRowValues
|
|
(
|
|
WCHAR * pwszRowURL, // [in] the URL of the row to be checked
|
|
IUnknown * pIUnk, // [in] ptr to the row interface
|
|
BOOL fFromRowset = TRUE // [in] whether it was obtained from a rowset
|
|
);
|
|
|
|
HRESULT VerifyRowValues
|
|
(
|
|
WCHAR * pwszRowURL // [in] the URL of the row to be checked
|
|
);
|
|
|
|
|
|
CSchema * RemoveSchema(CSchema *pSchema);
|
|
CSchema * RemoveSchema(WCHAR *pwszURL); // [in] URL associated with the schema
|
|
|
|
};
|
|
|
|
|
|
#endif _CTree_HPP_ |