986 lines
24 KiB
C++
986 lines
24 KiB
C++
// clib.hpp
|
|
#include "Extralib.h"
|
|
|
|
typedef struct {
|
|
GUID guidSchema;
|
|
ULONG cRestrictions;
|
|
ULONG *rgRestrictions;
|
|
} SSchemaEntry;
|
|
|
|
// this class contains info related to various schema constraints
|
|
// this should be updated based on the spec
|
|
// there is no programmatical meaning to get this info, aside
|
|
// using this class
|
|
class CSchemaInfo{
|
|
public:
|
|
|
|
// number of schemas that have info
|
|
ULONG m_cSchemas;
|
|
|
|
SSchemaEntry *m_rgSchemaEntry;
|
|
|
|
CSchemaInfo();
|
|
~CSchemaInfo() {SAFE_FREE(m_rgSchemaEntry);}
|
|
|
|
LONG GetSchemaIndex(GUID guidSchema);
|
|
SSchemaEntry *operator[](GUID guidSchema);
|
|
}; //CSchemaInfo
|
|
|
|
|
|
|
|
//==================================================================
|
|
//
|
|
// Classes related to schema rowsets
|
|
//
|
|
//==================================================================
|
|
|
|
|
|
// this class should be used to access data in
|
|
// schema rowsets as conveninent as possible and
|
|
// still allow some basic testing
|
|
class CSchemaRowset
|
|
{
|
|
private:
|
|
IDBSchemaRowset *m_pIDBSR;
|
|
|
|
// @cmember returns the index of the given schema in the array or -1 if it doesn't exist
|
|
LONG GetSchemaIndex(GUID guidSchema);
|
|
CSchemaInfo m_SchemaInfo;
|
|
|
|
public:
|
|
ULONG m_cSchemas;
|
|
// for speed, this could be turned into a hash table
|
|
GUID *m_rgSchemas;
|
|
ULONG *m_rgRestrictionSupport;
|
|
|
|
CSchemaRowset(
|
|
IUnknown *pIUnknown, // pointer to the session object
|
|
BOOL fQI = TRUE // whether the interface should
|
|
// be QI-ed for, or it is already
|
|
// an IDBSchemaRowset interface
|
|
);
|
|
|
|
~CSchemaRowset();
|
|
|
|
operator IDBSchemaRowset*() {
|
|
return m_pIDBSR;}
|
|
|
|
void FreeCache() {
|
|
SAFE_FREE(m_rgSchemas);
|
|
SAFE_FREE(m_rgRestrictionSupport);
|
|
m_cSchemas = 0;
|
|
};
|
|
|
|
// @cmember This method calls IDBSchemaRowset::GetSchemas and
|
|
// caches the results
|
|
HRESULT GetSchemas();
|
|
|
|
// @cmember Tells whether a certain schema is supported or not
|
|
HRESULT IsSchemaSupported(GUID guidSchema);
|
|
|
|
// @cmember Restriction support for a certain schema
|
|
HRESULT GetRestrictionSupport(GUID guidSchema, ULONG *pRestSupp);
|
|
|
|
// @ cmember Calls GetRowset on the IDBSchemaRowset interface and
|
|
// does some basic checking
|
|
HRESULT GetRowset(
|
|
IUnknown * pUnkOuter,
|
|
REFGUID rguidSchema,
|
|
ULONG cRestrictions,
|
|
const VARIANT rgRestrictions[],
|
|
REFIID riid,
|
|
ULONG cPropertySets,
|
|
DBPROPSET rgPropertySets[],
|
|
IUnknown ** ppRowset
|
|
);
|
|
|
|
}; //CSchemaRowset
|
|
|
|
|
|
|
|
|
|
|
|
class CComfRowset : public CRowset{
|
|
public:
|
|
CComfRowset(WCHAR* pwszTestCaseName = INVALID(WCHAR*)): CRowset(pwszTestCaseName) {;}
|
|
virtual ~CComfRowset() {CRowset::~CRowset();}
|
|
|
|
DBSTATUS *GetStatus(DBCOUNTITEM cBinding)
|
|
{
|
|
DBBINDING *pBinding = &m_rgBinding[cBinding];
|
|
|
|
if (STATUS_IS_BOUND(*pBinding))
|
|
return (DBSTATUS*)((BYTE*)m_pData + pBinding->obStatus);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
LPVOID *GetValue(DBCOUNTITEM cBinding)
|
|
{
|
|
DBBINDING *pBinding = &m_rgBinding[cBinding];
|
|
DBSTATUS *pStatus = GetStatus(cBinding);
|
|
|
|
if (VALUE_IS_BOUND(*pBinding) && DBSTATUS_S_OK == *pStatus)
|
|
return (LPVOID*)&VALUE_BINDING(m_rgBinding[cBinding], m_pData);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
DBBYTEOFFSET *GetLength(DBCOUNTITEM cBinding)
|
|
{
|
|
DBBINDING *pBinding = &m_rgBinding[cBinding];
|
|
DBSTATUS *pStatus = GetStatus(cBinding);
|
|
|
|
if (LENGTH_IS_BOUND(*pBinding) && DBSTATUS_S_OK == *pStatus)
|
|
return (DBBYTEOFFSET*)((BYTE*)m_pData+pBinding->obLength);
|
|
else
|
|
return NULL;
|
|
}
|
|
}; //CComfRowset
|
|
|
|
|
|
|
|
|
|
// this class gets the names of the catalogs on a server
|
|
class CCatalogs
|
|
{
|
|
protected:
|
|
DBORDINAL m_cCatalogs;
|
|
WCHAR **m_rgCatalogs;
|
|
|
|
public:
|
|
IUnknown *m_pSessionIUnknown;
|
|
IDBProperties *m_pIDBProperties;
|
|
|
|
CCatalogs(IUnknown *pSessionIUnknown);
|
|
~CCatalogs();
|
|
|
|
WCHAR *operator[](DBORDINAL index);
|
|
DBORDINAL cCatalogs() {
|
|
return m_cCatalogs;
|
|
}
|
|
WCHAR **rgCatalogs(){
|
|
return m_rgCatalogs;
|
|
}
|
|
|
|
BOOL GetCurrentCatalog(WCHAR **ppwszCatalogName);
|
|
HRESULT SetCurrentCatalog(WCHAR *pwszCatalogName);
|
|
HRESULT ChangeCurrentCatalog(WCHAR **ppwszCatalogName = NULL);
|
|
|
|
HRESULT DoesCatalogExist(WCHAR *pwszCatalogName) {
|
|
// checks whether a given catalog exists in the data source
|
|
if (!pwszCatalogName)
|
|
return E_INVALIDARG;
|
|
|
|
if (!m_rgCatalogs)
|
|
{
|
|
ASSERT(0 == m_cCatalogs);
|
|
return E_FAIL;
|
|
}
|
|
|
|
for (ULONG index=0; index < m_cCatalogs; index++)
|
|
{
|
|
if (0 == wcscmp(pwszCatalogName, m_rgCatalogs[index]))
|
|
return S_OK;
|
|
}
|
|
|
|
return E_FAIL;
|
|
}
|
|
}; // CCatalogs
|
|
|
|
|
|
|
|
class CAccessibleCatalogs: public CCatalogs
|
|
{
|
|
public:
|
|
CAccessibleCatalogs(IUnknown *pSessionIUnknown);
|
|
~CAccessibleCatalogs() {}
|
|
}; //CAccessibleCatalogs
|
|
|
|
|
|
|
|
// this class grabs data related to all the constraints of a table
|
|
class CConstraints
|
|
{
|
|
private:
|
|
DBCOUNTITEM m_cConstraints;
|
|
DBCONSTRAINTDESC *m_rgConstraints;
|
|
// cache for criteria
|
|
WCHAR *m_pwszTableCatalog;
|
|
WCHAR *m_pwszTableSchema;
|
|
WCHAR *m_pwszTableName;
|
|
WCHAR *m_pwszConsCatalog;
|
|
WCHAR *m_pwszConsSchema;
|
|
WCHAR *m_pwszConsName;
|
|
IUnknown *m_pSessionIUnknown;
|
|
IUnknown *m_pDSOIUnknown;
|
|
|
|
// store all the constraint names you have already given away
|
|
// assumptionis made that after they are no longer in use, they
|
|
// are returned to the available name space
|
|
DBORDINAL m_cMaxConsNames;
|
|
DBORDINAL m_cConsNames;
|
|
WCHAR **m_rgConsNames;
|
|
|
|
LONG GetConsNameIndex(WCHAR *pwszConsName);
|
|
|
|
HRESULT ParseQualTableName(WCHAR *pwszQualTableName,
|
|
WCHAR **pwszTableCatalog,
|
|
WCHAR **pwszTableSchema,
|
|
WCHAR **pwszTableName);
|
|
|
|
public:
|
|
|
|
CConstraints(IUnknown *pSessionIUnknown);
|
|
|
|
~CConstraints();
|
|
|
|
HRESULT GetConstraints(
|
|
WCHAR *pwszTableCatalog, // [in] table catalog restriction
|
|
WCHAR *pwszTableSchema, // [in] table schema restriction
|
|
WCHAR *pwszTableName, // [in] table name restriction (better not be NULL!)
|
|
WCHAR *pwszConsCatalog, // [in] constraint catalog restriction
|
|
WCHAR *pwszConsSchema, // [in] constraint schema restriction
|
|
WCHAR *pwszConsName // [in] constraint name restriction
|
|
);
|
|
|
|
DBCOUNTITEM GetConstrNo(){
|
|
return m_cConstraints;}
|
|
|
|
DBCONSTRAINTDESC *GetConstraints(){
|
|
return m_rgConstraints;}
|
|
|
|
DBCONSTRAINTDESC *operator[](DBID *pConstraintID);
|
|
|
|
HRESULT CheckIncludedConstraints(DBORDINAL cConsDesc, DBCONSTRAINTDESC *rgConsDesc);
|
|
|
|
// @cmember This method checks whether the all the previously existent constraints still exist
|
|
// and whether the constraints in the rgConsDesc array were added
|
|
HRESULT CheckAddConstraints(DBORDINAL cConsDesc, DBCONSTRAINTDESC *rgConsDesc);
|
|
|
|
// @cmember Check whether a certain constraint was dropped from the table
|
|
HRESULT CheckDropConstraint(DBCONSTRAINTDESC *pConsDesc);
|
|
|
|
// checked whether the constraint array is the same as last time
|
|
HRESULT AreConstraintsPreserved();
|
|
|
|
// @cmember Check whether a given constraint exists
|
|
HRESULT DoesConstraintExist(WCHAR *pwszConsName, BOOL &fExist);
|
|
|
|
// @cmember Build a name for a constraint
|
|
HRESULT MakeConstraintName(WCHAR **ppwszConsName);
|
|
|
|
// @cmember Return name that is already been used for constraints
|
|
HRESULT ReturnConstraintName(WCHAR *pwszConsName);
|
|
|
|
// @cmember Book constraint name
|
|
HRESULT BookConstraintName(WCHAR *pwszConsName);
|
|
}; //CConstraints
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// this class grabs data related to all the check constraints of a table
|
|
class CCheckConsRowset
|
|
{
|
|
private:
|
|
WCHAR *m_pwszConsCatalog;
|
|
WCHAR *m_pwszConsSchema;
|
|
WCHAR *m_pwszConsName;
|
|
|
|
IUnknown *m_pSessionIUnknown;
|
|
IUnknown *m_pDSOIUnknown;
|
|
|
|
LONG m_lCrtPos;
|
|
|
|
CTable *m_pTable;
|
|
CComfRowset m_Rowset;
|
|
|
|
public:
|
|
|
|
static BOOL s_fMetadataInitialized;
|
|
static BOOL s_fSchemaSupported;
|
|
static BOOL s_fConsCatalogR;
|
|
static BOOL s_fConsSchemaR;
|
|
static BOOL s_fConsNameR;
|
|
|
|
static BOOL IsSchemaSupported() {
|
|
ASSERT(s_fMetadataInitialized);
|
|
return s_fSchemaSupported;
|
|
}
|
|
|
|
CCheckConsRowset(IUnknown *pSessionIUnknown);
|
|
|
|
~CCheckConsRowset();
|
|
|
|
HRESULT GetCheckConstraints(
|
|
WCHAR *pwszConsCatalog, // [in] constraint catalog restriction
|
|
WCHAR *pwszConsSchema, // [in] constraint schema restriction
|
|
WCHAR *pwszConsName // [in] constraint name restriction
|
|
);
|
|
|
|
DBCOUNTITEM GetConstrNo();
|
|
|
|
WCHAR *operator[](DBORDINAL index);
|
|
}; //CCheckConsRowset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// this class grabs data related to the PK constraint of a table
|
|
class CPKRowset
|
|
{
|
|
private:
|
|
WCHAR *m_pwszTableCatalog;
|
|
WCHAR *m_pwszTableSchema;
|
|
WCHAR *m_pwszTableName;
|
|
|
|
WCHAR *m_pwszPKName;
|
|
|
|
IUnknown *m_pSessionIUnknown;
|
|
IUnknown *m_pDSOIUnknown;
|
|
|
|
LONG m_lCrtPos;
|
|
|
|
CTable *m_pTable;
|
|
CComfRowset m_Rowset;
|
|
|
|
public:
|
|
|
|
static BOOL s_fMetadataInitialized;
|
|
static BOOL s_fSchemaSupported;
|
|
static BOOL s_fTableCatalogR;
|
|
static BOOL s_fTableSchemaR;
|
|
static BOOL s_fTableNameR;
|
|
|
|
static BOOL IsSchemaSupported() {
|
|
ASSERT(s_fMetadataInitialized);
|
|
return s_fSchemaSupported;
|
|
}
|
|
|
|
CPKRowset(IUnknown *pSessionIUnknown);
|
|
|
|
~CPKRowset();
|
|
|
|
HRESULT GetPrimaryKeys(
|
|
WCHAR *pwszTableCatalog, // [in] constraint catalog restriction
|
|
WCHAR *pwszTableSchema, // [in] constraint schema restriction
|
|
WCHAR *pwszTableName // [in] constraint name restriction
|
|
);
|
|
|
|
DBCOUNTITEM GetConstrNo();
|
|
|
|
DBID *operator[](DBORDINAL index);
|
|
|
|
WCHAR *GetPKName();
|
|
}; //CPKRowset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// this class grabs data related to all the FK constraints of a table
|
|
class CFKRowset
|
|
{
|
|
private:
|
|
WCHAR *m_pwszTableCatalog;
|
|
WCHAR *m_pwszTableSchema;
|
|
WCHAR *m_pwszTableName;
|
|
|
|
WCHAR *m_pwszFKName;
|
|
|
|
WCHAR *m_pwszReferencedTableCatalog;
|
|
WCHAR *m_pwszReferencedTableSchema;
|
|
WCHAR *m_pwszReferencedTableName;
|
|
|
|
IUnknown *m_pSessionIUnknown;
|
|
IUnknown *m_pDSOIUnknown;
|
|
|
|
LONG m_lCrtPos;
|
|
|
|
CTable *m_pTable;
|
|
CComfRowset m_Rowset;
|
|
|
|
DBID *m_pCrtReferencedColID;
|
|
DBID *m_pCrtFKColID;
|
|
|
|
WCHAR *m_pwszUpdateRule;
|
|
WCHAR *m_pwszDeleteRule;
|
|
|
|
static DBUPDELRULE StringToUpDelRule(WCHAR *pwszRule){
|
|
ASSERT(pwszRule);
|
|
if (0 == wcscmp(L"CASCADE", pwszRule))
|
|
return DBUPDELRULE_CASCADE;
|
|
else if (0 == wcscmp(L"SET NULL", pwszRule))
|
|
return DBUPDELRULE_SETNULL;
|
|
else if (0 == wcscmp(L"SET DEFAULT", pwszRule))
|
|
return DBUPDELRULE_SETDEFAULT;
|
|
else ASSERT(0 == wcscmp(L"NO ACTION", pwszRule));
|
|
return DBUPDELRULE_NOACTION;
|
|
}
|
|
|
|
public:
|
|
|
|
static BOOL s_fMetadataInitialized;
|
|
static BOOL s_fSchemaSupported;
|
|
static BOOL s_fTableCatalogR;
|
|
static BOOL s_fTableSchemaR;
|
|
static BOOL s_fTableNameR;
|
|
|
|
static BOOL IsSchemaSupported() {
|
|
ASSERT(s_fMetadataInitialized);
|
|
return s_fSchemaSupported;
|
|
}
|
|
|
|
CFKRowset(IUnknown *pSessionIUnknown);
|
|
|
|
~CFKRowset();
|
|
|
|
HRESULT GetForeignKeys(
|
|
WCHAR *pwszTableCatalog, // [in] constraint catalog restriction
|
|
WCHAR *pwszTableSchema, // [in] constraint schema restriction
|
|
WCHAR *pwszTableName, // [in] constraint name restriction
|
|
WCHAR *pwszFKName // [in] foreign key constraint
|
|
);
|
|
|
|
DBCOUNTITEM GetConstrNo();
|
|
|
|
BOOL MoveToRow(DBORDINAL index);
|
|
|
|
WCHAR *GetReferencedTableName();
|
|
WCHAR *GetFKName();
|
|
DBID *GetCrtReferencedColID() {
|
|
return m_pCrtReferencedColID;
|
|
}
|
|
DBID *GetCrtFKColID() {
|
|
return m_pCrtFKColID;
|
|
}
|
|
DBUPDELRULE GetUpdateRule() {
|
|
return StringToUpDelRule(m_pwszUpdateRule);
|
|
}
|
|
DBUPDELRULE GetDeleteRule() {
|
|
return StringToUpDelRule(m_pwszDeleteRule);
|
|
}
|
|
}; //CFKRowset
|
|
|
|
|
|
|
|
|
|
// this class grabs data related key column usage
|
|
class CKeyColumnUsageRowset
|
|
{
|
|
private:
|
|
WCHAR *m_pwszTableCatalog;
|
|
WCHAR *m_pwszTableSchema;
|
|
WCHAR *m_pwszTableName;
|
|
|
|
WCHAR *m_pwszConsCatalog;
|
|
WCHAR *m_pwszConsSchema;
|
|
WCHAR *m_pwszConsName;
|
|
|
|
IUnknown *m_pSessionIUnknown;
|
|
IUnknown *m_pDSOIUnknown;
|
|
|
|
LONG m_lCrtPos;
|
|
|
|
CTable *m_pTable;
|
|
CComfRowset m_Rowset;
|
|
|
|
DBID *m_pCrtColID;
|
|
|
|
public:
|
|
|
|
static BOOL s_fMetadataInitialized;
|
|
static BOOL s_fSchemaSupported;
|
|
|
|
static BOOL s_fTableCatalogR;
|
|
static BOOL s_fTableSchemaR;
|
|
static BOOL s_fTableNameR;
|
|
|
|
static BOOL s_fConsCatalogR;
|
|
static BOOL s_fConsSchemaR;
|
|
static BOOL s_fConsNameR;
|
|
|
|
static BOOL IsSchemaSupported() {
|
|
ASSERT(s_fMetadataInitialized);
|
|
return s_fSchemaSupported;
|
|
}
|
|
|
|
CKeyColumnUsageRowset(IUnknown *pSessionIUnknown);
|
|
|
|
~CKeyColumnUsageRowset();
|
|
|
|
HRESULT GetKeyColumnUsage(
|
|
WCHAR *pwszTableCatalog, // [in] constraint catalog restriction
|
|
WCHAR *pwszTableSchema, // [in] constraint schema restriction
|
|
WCHAR *pwszTableName, // [in] constraint name restriction
|
|
WCHAR *pwszConsCatalog, // [in] constraint catalog restriction
|
|
WCHAR *pwszConsSchema, // [in] constraint schema restriction
|
|
WCHAR *pwszConsName // [in] constraint name restriction
|
|
);
|
|
|
|
DBCOUNTITEM GetConstrNo();
|
|
|
|
BOOL MoveToRow(DBORDINAL index);
|
|
|
|
WCHAR *GetConstraintName() {
|
|
return m_pwszConsName;
|
|
}
|
|
DBID *GetCrtColID() {
|
|
return m_pCrtColID;
|
|
}
|
|
}; //CKeyColumnUsageRowset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//===============================================================================
|
|
//
|
|
// helper class for DBCONSTRAINTDESC
|
|
//
|
|
//===============================================================================
|
|
class CConsDesc
|
|
{
|
|
protected:
|
|
DBCONSTRAINTDESC *m_pConsDesc;
|
|
BOOL m_fFreeMem;
|
|
|
|
public:
|
|
static IUnknown *s_pDSOIUnknown;
|
|
static IUnknown *s_pSessionIUnknown;
|
|
static CConstraints *s_pConstraints;
|
|
static BOOL s_fInsideTransaction;
|
|
|
|
CConsDesc(
|
|
DBCONSTRAINTTYPE ConsType,
|
|
DBDEFERRABILITY Def = 0);
|
|
|
|
CConsDesc(DBCONSTRAINTDESC *pConsDesc);
|
|
|
|
~CConsDesc();
|
|
|
|
virtual BOOL IsEqual(CConsDesc *pConsDesc) {
|
|
return pConsDesc &&
|
|
pConsDesc->GetConstraintType() == GetConstraintType()
|
|
&& pConsDesc->GetDeferrability() == GetDeferrability()
|
|
&& CompareDBID(*(pConsDesc->GetConstraintID()), *GetConstraintID());
|
|
}
|
|
|
|
operator DBCONSTRAINTDESC*(){
|
|
return m_pConsDesc;}
|
|
|
|
operator DBID*(){
|
|
return m_pConsDesc->pConstraintID;}
|
|
|
|
// interface methods for constraint DBID
|
|
void SetConstraintName(WCHAR *pwszConstraintName);
|
|
DBID *GetConstraintID() {
|
|
return m_pConsDesc->pConstraintID;}
|
|
DBID *SetConstraintID(DBID *pConstraintID);
|
|
|
|
// interface methods for constraint type
|
|
DBCONSTRAINTTYPE SetConstraintType(DBCONSTRAINTTYPE ConstraintType){
|
|
return m_pConsDesc->ConstraintType = ConstraintType;}
|
|
DBCONSTRAINTTYPE GetConstraintType(){
|
|
return m_pConsDesc->ConstraintType;}
|
|
|
|
// interface methods for constraint deferrability
|
|
DBDEFERRABILITY SetDeferrability(DBDEFERRABILITY Deferrability){
|
|
return m_pConsDesc->Deferrability = Deferrability;}
|
|
DBDEFERRABILITY GetDeferrability(){
|
|
return m_pConsDesc->Deferrability;}
|
|
|
|
DBCONSTRAINTDESC *GetConsDescOwnership(){
|
|
if (m_fFreeMem)
|
|
{
|
|
m_fFreeMem = FALSE;
|
|
return m_pConsDesc;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
virtual HRESULT CopyTo(DBCONSTRAINTDESC *pCD);
|
|
|
|
// @cmember Build a name for the constraint
|
|
HRESULT MakeConstraintName();
|
|
|
|
virtual HRESULT GetInfoFromSchemaRowset(
|
|
WCHAR *pwszTableCatalog,
|
|
WCHAR *pwszTableSchema,
|
|
WCHAR *pwszTableName,
|
|
WCHAR *pwszConsCatalog,
|
|
WCHAR *pwszConsSchema,
|
|
WCHAR *pwszConsName
|
|
) { return S_OK;}
|
|
}; //CConsDesc
|
|
|
|
|
|
|
|
|
|
class CKeyConstraint: public CConsDesc
|
|
{
|
|
protected:
|
|
DBORDINAL m_cMaxColumns;
|
|
|
|
DBID *AddColumnID(
|
|
DBORDINAL *pcMaxColumns, // [in/out] maximum number of columns
|
|
DBORDINAL *pcColumns, // [in/out] number of columns
|
|
DBID **prgColumnList, // [in/out] array of columns
|
|
DBID *pColumnID // [in] column ID to be added
|
|
);
|
|
|
|
HRESULT ReleaseColumnIDs(
|
|
DBORDINAL *pcMaxColumns, // [in] maximum number of columns
|
|
DBORDINAL *pcColumns, // [in/out] number of columns
|
|
DBID **prgColumnList // [in] array of columns
|
|
);
|
|
|
|
LONG GetColumnIndex(
|
|
DBORDINAL ulColumns,
|
|
DBID *rgColumnList,
|
|
DBID *pColumnID
|
|
);
|
|
|
|
public:
|
|
CKeyConstraint(
|
|
DBCONSTRAINTTYPE ConsType,
|
|
DBDEFERRABILITY Def = 0);
|
|
|
|
CKeyConstraint(DBCONSTRAINTDESC *pConsDesc) : CConsDesc(pConsDesc){
|
|
ASSERT(NULL != pConsDesc);
|
|
m_cMaxColumns = m_pConsDesc->cColumns;
|
|
}
|
|
|
|
~CKeyConstraint() {;}
|
|
|
|
DBID *rgColumnList() {
|
|
return m_pConsDesc->rgColumnList;}
|
|
DBORDINAL cColumns() {
|
|
return m_pConsDesc->cColumns;}
|
|
|
|
// add a column to rgColumnList
|
|
DBID *AddColumn(DBID *pColumnID) {
|
|
return AddColumnID( &m_cMaxColumns,
|
|
&m_pConsDesc->cColumns,
|
|
&m_pConsDesc->rgColumnList,
|
|
pColumnID);
|
|
}
|
|
|
|
HRESULT ReleaseColumnList() {
|
|
return ReleaseColumnIDs(&m_cMaxColumns,
|
|
&m_pConsDesc->cColumns,
|
|
&m_pConsDesc->rgColumnList);
|
|
}
|
|
|
|
HRESULT SetConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL cCol,
|
|
DBORDINAL *rgCol,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
);
|
|
|
|
HRESULT SetConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL indexCol,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
)
|
|
{
|
|
return SetConstraint(pTable, 1, &indexCol, Deferrability);
|
|
}
|
|
|
|
HRESULT CopyTo(DBCONSTRAINTDESC *pCD);
|
|
|
|
LONG GetColumnIndex(DBID *pColumnID) {
|
|
return GetColumnIndex(
|
|
m_pConsDesc->cColumns,
|
|
m_pConsDesc->rgColumnList,
|
|
pColumnID);
|
|
}
|
|
|
|
BOOL IsEqual(CConsDesc*);
|
|
}; // CKeyConstraint
|
|
|
|
|
|
|
|
|
|
class CUniqueCons: public CKeyConstraint
|
|
{
|
|
public:
|
|
CUniqueCons(DBDEFERRABILITY Def = 0) :
|
|
CKeyConstraint(DBCONSTRAINTTYPE_UNIQUE, Def) {;}
|
|
|
|
CUniqueCons(DBCONSTRAINTDESC *pConsDesc) : CKeyConstraint(pConsDesc){
|
|
m_pConsDesc->ConstraintType = DBCONSTRAINTTYPE_UNIQUE;
|
|
}
|
|
|
|
~CUniqueCons() {;}
|
|
|
|
HRESULT GetInfoFromSchemaRowset(
|
|
WCHAR *pwszTableCatalog,
|
|
WCHAR *pwszTableSchema,
|
|
WCHAR *pwszTableName,
|
|
WCHAR *pwszConsCatalog,
|
|
WCHAR *pwszConsSchema,
|
|
WCHAR *pwszConsName
|
|
);
|
|
}; //CUniqueCons
|
|
|
|
|
|
|
|
class CPrimaryKeyCons: public CKeyConstraint
|
|
{
|
|
public:
|
|
CPrimaryKeyCons(
|
|
DBDEFERRABILITY Def = 0) :
|
|
CKeyConstraint(DBCONSTRAINTTYPE_PRIMARYKEY, Def) {;}
|
|
|
|
CPrimaryKeyCons(DBCONSTRAINTDESC *pConsDesc) : CKeyConstraint(pConsDesc){
|
|
m_pConsDesc->ConstraintType = DBCONSTRAINTTYPE_PRIMARYKEY;
|
|
}
|
|
|
|
~CPrimaryKeyCons() {;}
|
|
|
|
HRESULT GetInfoFromSchemaRowset(
|
|
WCHAR *pwszTableCatalog,
|
|
WCHAR *pwszTableSchema,
|
|
WCHAR *pwszTableName,
|
|
WCHAR *pwszConsCatalog,
|
|
WCHAR *pwszConsSchema,
|
|
WCHAR *pwszConsName
|
|
);
|
|
}; //CPrimaryKeyCons
|
|
|
|
|
|
|
|
class CForeignKeyCons: public CKeyConstraint
|
|
{
|
|
protected:
|
|
DBORDINAL m_cMaxForeignKeyColumns;
|
|
|
|
public:
|
|
CForeignKeyCons(
|
|
DBID *pReferencedID = NULL,
|
|
DBMATCHTYPE MatchType = DBMATCHTYPE_NONE,
|
|
DBUPDELRULE UpdateRule = DBUPDELRULE_NOACTION,
|
|
DBUPDELRULE DeleteRule = DBUPDELRULE_NOACTION,
|
|
DBDEFERRABILITY Def = 0);
|
|
|
|
CForeignKeyCons(DBCONSTRAINTDESC *pConsDesc) : CKeyConstraint(pConsDesc){
|
|
m_pConsDesc->ConstraintType = DBCONSTRAINTTYPE_FOREIGNKEY;
|
|
m_cMaxForeignKeyColumns = m_pConsDesc->cForeignKeyColumns;
|
|
}
|
|
|
|
~CForeignKeyCons() {;}
|
|
|
|
DBID *rgForeignKeyColumnList() {
|
|
return m_pConsDesc->rgForeignKeyColumnList;}
|
|
DBORDINAL cForeignKeyColumns() {
|
|
return m_pConsDesc->cForeignKeyColumns;}
|
|
|
|
// interface methods for handling the referenced table
|
|
DBID *SetReferencedTableID(DBID *pDBID);
|
|
DBID *GetReferencedTableID() {
|
|
return m_pConsDesc->pReferencedTableID;
|
|
}
|
|
|
|
// interface methods for update/delete rules and match type
|
|
DBUPDELRULE SetUpdateRule(DBUPDELRULE UpdateRule) {
|
|
return m_pConsDesc->UpdateRule = UpdateRule; }
|
|
DBUPDELRULE GetUpdateRule() {
|
|
return m_pConsDesc->UpdateRule;}
|
|
DBUPDELRULE SetDeleteRule(DBUPDELRULE DeleteRule) {
|
|
return m_pConsDesc->DeleteRule = DeleteRule; }
|
|
DBUPDELRULE GetDeleteRule() {
|
|
return m_pConsDesc->DeleteRule;}
|
|
DBMATCHTYPE SetMatchType(DBMATCHTYPE MatchType) {
|
|
return m_pConsDesc->MatchType = MatchType;}
|
|
DBMATCHTYPE GetMatchType() {
|
|
return m_pConsDesc->MatchType;}
|
|
|
|
// add a foreign key column to rgForeignKeyColumnList
|
|
DBID *AddForeignKeyColumn(DBID *pColumnID) {
|
|
return AddColumnID( &m_cMaxForeignKeyColumns,
|
|
&m_pConsDesc->cForeignKeyColumns,
|
|
&m_pConsDesc->rgForeignKeyColumnList,
|
|
pColumnID);
|
|
}
|
|
|
|
HRESULT ReleaseForeignKeyColumnList() {
|
|
return ReleaseColumnIDs(&m_cMaxForeignKeyColumns,
|
|
&m_pConsDesc->cForeignKeyColumns,
|
|
&m_pConsDesc->rgForeignKeyColumnList);
|
|
}
|
|
|
|
HRESULT SetConstraint(
|
|
CTable *pBaseTable,
|
|
DBORDINAL cBaseCol,
|
|
DBORDINAL *rgBaseCol,
|
|
CTable *pReferencedTable,
|
|
DBORDINAL cReferencedCol,
|
|
DBORDINAL *rgReferencedCol,
|
|
DBMATCHTYPE MatchType = DBMATCHTYPE_FULL,
|
|
DBUPDELRULE UpdateRule = DBUPDELRULE_NOACTION,
|
|
DBUPDELRULE DeleteRule = DBUPDELRULE_NOACTION,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
);
|
|
|
|
HRESULT CopyTo(DBCONSTRAINTDESC *pCD);
|
|
|
|
HRESULT GetInfoFromSchemaRowset(
|
|
WCHAR *pwszTableCatalog,
|
|
WCHAR *pwszTableSchema,
|
|
WCHAR *pwszTableName,
|
|
WCHAR *pwszConsCatalog,
|
|
WCHAR *pwszConsSchema,
|
|
WCHAR *pwszConsName
|
|
);
|
|
|
|
LONG GetFKColumnIndex(DBID *pColumnID) {
|
|
return GetColumnIndex(
|
|
m_pConsDesc->cForeignKeyColumns,
|
|
m_pConsDesc->rgForeignKeyColumnList,
|
|
pColumnID);
|
|
}
|
|
|
|
BOOL IsEqual(CConsDesc*);
|
|
}; //CForeignKeyCons
|
|
|
|
|
|
|
|
class CCheckCons: public CConsDesc
|
|
{
|
|
public:
|
|
CCheckCons(
|
|
WCHAR *pwszConstraintText = NULL,
|
|
DBMATCHTYPE MatchType = DBMATCHTYPE_NONE,
|
|
DBDEFERRABILITY Def = 0) :
|
|
CConsDesc(DBCONSTRAINTTYPE_CHECK, Def)
|
|
{
|
|
m_pConsDesc->MatchType = MatchType;
|
|
m_pConsDesc->pwszConstraintText = wcsDuplicate(pwszConstraintText);
|
|
}
|
|
|
|
CCheckCons(DBCONSTRAINTDESC *pConsDesc) : CConsDesc(pConsDesc){
|
|
m_pConsDesc->ConstraintType = DBCONSTRAINTTYPE_CHECK;
|
|
}
|
|
|
|
~CCheckCons() {;}
|
|
|
|
void SetConstraintText(WCHAR *pwszConstraintText){
|
|
SAFE_FREE(m_pConsDesc->pwszConstraintText);
|
|
m_pConsDesc->pwszConstraintText = wcsDuplicate(pwszConstraintText);
|
|
}
|
|
|
|
WCHAR *GetConstraintText(){
|
|
return m_pConsDesc->pwszConstraintText;
|
|
}
|
|
|
|
HRESULT CopyTo(DBCONSTRAINTDESC *pCD);
|
|
|
|
HRESULT GetInfoFromSchemaRowset(
|
|
WCHAR *pwszTableCatalog,
|
|
WCHAR *pwszTableSchema,
|
|
WCHAR *pwszTableName,
|
|
WCHAR *pwszConsCatalog,
|
|
WCHAR *pwszConsSchema,
|
|
WCHAR *pwszConsName
|
|
);
|
|
|
|
HRESULT SetIsNotNULLCheckConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL ulCol
|
|
);
|
|
|
|
HRESULT SetIsNotNULLCheckConstraint(WCHAR*);
|
|
|
|
HRESULT SetLTCheckConstraint(
|
|
DBCOLUMNDESC *pColDesc,
|
|
DBORDINAL ulSeed
|
|
);
|
|
|
|
HRESULT SetLTCheckConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL ulCol,
|
|
DBORDINAL ulSeed
|
|
);
|
|
}; //CCheckCons
|
|
|
|
|
|
|
|
class CConsDescArray
|
|
{
|
|
protected:
|
|
DBORDINAL m_cMaxConsDesc;
|
|
DBORDINAL m_cConsDesc;
|
|
DBCONSTRAINTDESC *m_rgConsDesc;
|
|
|
|
public:
|
|
CConsDescArray() {
|
|
m_cMaxConsDesc = 0;
|
|
m_cConsDesc = 0;
|
|
m_rgConsDesc = NULL;
|
|
}
|
|
|
|
~CConsDescArray() {
|
|
FreeConstraintDesc(&m_cConsDesc, &m_rgConsDesc);
|
|
}
|
|
|
|
operator ULONG() {
|
|
ASSERT(m_cConsDesc < ULONG_MAX);
|
|
return (ULONG)m_cConsDesc;
|
|
}
|
|
|
|
operator DBCONSTRAINTDESC*() {
|
|
return m_rgConsDesc;
|
|
}
|
|
|
|
DBCONSTRAINTDESC *AddConsDesc(CConsDesc &cons);
|
|
}; //CConsDescArray
|
|
|
|
class CConstraintRestrictions
|
|
{
|
|
public:
|
|
WCHAR *m_pwszTableCatalog;
|
|
WCHAR *m_pwszTableSchema;
|
|
WCHAR *m_pwszTableName;
|
|
WCHAR *m_pwszConsCatalog;
|
|
WCHAR *m_pwszConsSchema;
|
|
WCHAR *m_pwszConsName;
|
|
CConsDesc *m_pConsDesc;
|
|
|
|
CConstraintRestrictions(
|
|
CConsDesc *pConsDesc,
|
|
WCHAR *pwszTableCatalog, // [in] table catalog restriction
|
|
WCHAR *pwszTableSchema, // [in] table schema restriction
|
|
WCHAR *pwszTableName, // [in] table name restriction (better not be NULL!)
|
|
WCHAR *pwszConsCatalog, // [in] constraint catalog restriction
|
|
WCHAR *pwszConsSchema, // [in] constraint schema restriction
|
|
WCHAR *pwszConsName // [in] constraint name restriction
|
|
)
|
|
{
|
|
m_pConsDesc = pConsDesc;
|
|
m_pwszTableCatalog = wcsDuplicate(pwszTableCatalog);
|
|
m_pwszTableSchema = wcsDuplicate(pwszTableSchema);
|
|
m_pwszTableName = wcsDuplicate(pwszTableName);
|
|
m_pwszConsCatalog = wcsDuplicate(pwszConsCatalog);
|
|
m_pwszConsSchema = wcsDuplicate(pwszConsSchema);
|
|
m_pwszConsName = wcsDuplicate(pwszConsName);
|
|
}
|
|
~CConstraintRestrictions()
|
|
{
|
|
PROVIDER_FREE(m_pwszTableCatalog);
|
|
PROVIDER_FREE(m_pwszTableSchema);
|
|
PROVIDER_FREE(m_pwszTableName);
|
|
PROVIDER_FREE(m_pwszConsCatalog);
|
|
PROVIDER_FREE(m_pwszConsSchema);
|
|
PROVIDER_FREE(m_pwszConsName);
|
|
}
|
|
}; //CConstraintRestrictions
|