32839 lines
1009 KiB
C++
32839 lines
1009 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright 1995-2000 Microsoft Corporation.
|
|
//
|
|
// @doc
|
|
//
|
|
// @module ITblDef.CPP | Source for ITableDefinition test module
|
|
//
|
|
#define DBINITCONSTANTS // Must be defined to initialize constants in OLEDB.H
|
|
#define INITGUID
|
|
|
|
#include "modstandard.hpp"
|
|
#include "itbldef.h"
|
|
#include "Extralib.h"
|
|
#include <initguid.h>
|
|
|
|
#include <process.h>
|
|
#include "clib.hpp"
|
|
|
|
#include "DataSource.hpp"
|
|
|
|
const ULONG cMaxName = 300;
|
|
|
|
// maximum columns allowed per constraint
|
|
const DBORDINAL cMaxColsPerCons = 16;
|
|
|
|
// Maximum combined column length of constraint
|
|
const DBORDINAL cMaxColLengthPerCons = 900;
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Module Values
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// {{ TCW_MODULE_GLOBALS
|
|
DECLARE_MODULE_CLSID = { 0xae3d5c1e, 0x2a0b, 0x11d1, { 0xaf, 0x9d, 0x00, 0xc0, 0x4f, 0xc2, 0x27, 0x93 }};
|
|
DECLARE_MODULE_NAME("ITableDefinition");
|
|
DECLARE_MODULE_OWNER("Microsoft");
|
|
DECLARE_MODULE_DESCRIP("The module tests the ITableDefinition interface");
|
|
DECLARE_MODULE_VERSION(795921705);
|
|
// TCW_WizardVersion(2)
|
|
// TCW_Automation(True)
|
|
// }} TCW_MODULE_GLOBALS_END
|
|
GUID guidModule = { 0xae3d5c1e, 0x2a0b, 0x11d1, { 0xaf, 0x9d, 0x00, 0xc0, 0x4f, 0xc2, 0x27, 0x93 }};
|
|
|
|
//Globals
|
|
BOOL g_fSQLOLEDB25 = FALSE;
|
|
|
|
// macros
|
|
#define FILL_PROP_SET(RGPROPSET_EL, NPROP, RGPROP, PROP_GUID) \
|
|
RGPROPSET_EL.cProperties = NPROP; \
|
|
RGPROPSET_EL.rgProperties = RGPROP; \
|
|
RGPROPSET_EL.guidPropertySet = PROP_GUID; \
|
|
if (NULL != RGPROP) \
|
|
memset(RGPROP, 0, NPROP*sizeof(DBPROP));
|
|
|
|
#define FILL_PROP(RGPROP_EL, PROPID, VAR_TYPE, VAR_MACRO, VAR_VALUE, OPTION) \
|
|
memset(&RGPROP_EL, 0, sizeof(DBPROP)); \
|
|
RGPROP_EL.dwPropertyID = PROPID; \
|
|
RGPROP_EL.vValue.vt = VAR_TYPE; \
|
|
VAR_MACRO(&RGPROP_EL.vValue) = VAR_VALUE; \
|
|
RGPROP_EL.dwOptions = OPTION;
|
|
|
|
#define INVALID_DBKIND 1001
|
|
|
|
class TCITableDefinition;
|
|
class CTransactionLocal;
|
|
class CAddUniqueConsTxnAdapter;
|
|
|
|
// define argument stru for threading function parameters
|
|
typedef struct inparam{
|
|
ULONG i;
|
|
TCITableDefinition *pObject;
|
|
} CInParam;
|
|
|
|
// the number of threads that will be created in the multithreading test variations
|
|
const int nThreads = 7; // must be less than 100 and greater than 1
|
|
// the dispatcher thread function
|
|
unsigned WINAPI ThreadProc(LPVOID lpvThreadParam);
|
|
|
|
void ReleaseAllColumnPropSets(
|
|
DBCOLUMNDESC *rgColumnDesc, // [in] aray to be release
|
|
DBORDINAL cColumnDesc // [in] no of elementrs in the array
|
|
);
|
|
|
|
ULONG nResidualTables;
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level initialization routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleInit(CThisTestModule * pThisTestModule)
|
|
{
|
|
TBEGIN;
|
|
ITableDefinition *pITableDefinition = NULL;
|
|
HRESULT hr;
|
|
|
|
nResidualTables = 0;
|
|
|
|
//Create the session
|
|
if(!ModuleCreateDBSession(pThisTestModule))
|
|
return FALSE;
|
|
|
|
g_pIOpenRowset = (IOpenRowset*)pThisTestModule->m_pIUnknown2;
|
|
CConsDesc::s_pSessionIUnknown = g_pIOpenRowset;
|
|
CConsDesc::s_pDSOIUnknown = pThisTestModule->m_pIUnknown;
|
|
CConsDesc::s_pConstraints = new CConstraints(g_pIOpenRowset);
|
|
CConsDesc::s_fInsideTransaction = FALSE;
|
|
|
|
if (!(hr=VerifyInterface(pThisTestModule->m_pIUnknown2, IID_ITableDefinition,
|
|
SESSION_INTERFACE, (IUnknown**)&pITableDefinition)))
|
|
{
|
|
odtLog << "ITableDefinition not supported!\n";
|
|
TESTB = TEST_SKIPPED;;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
if (!(hr=VerifyInterface(pThisTestModule->m_pIUnknown, IID_IDBInitialize,
|
|
DATASOURCE_INTERFACE, (IUnknown**)&g_pIDBInitialize)))
|
|
{
|
|
odtLog << "IDBInitialize not supported!\n";
|
|
TESTB = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
if (IsSQLProvider())
|
|
{
|
|
if (GetModInfo()->GetProviderVer() && wcsncmp(GetModInfo()->GetProviderVer(), L"07", 2)==0)
|
|
g_fSQLOLEDB25 = TRUE;
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITableDefinition);
|
|
TRETURN;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level termination routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleTerminate(CThisTestModule * pThisTestModule)
|
|
{
|
|
SAFE_DELETE( CConsDesc::s_pConstraints);
|
|
CConsDesc::s_pSessionIUnknown = NULL;
|
|
CConsDesc::s_pDSOIUnknown = NULL;
|
|
if (0 < nResidualTables)
|
|
odtLog << "Total number of residual tables: " << nResidualTables << "\n";
|
|
SAFE_RELEASE(g_pIDBInitialize);
|
|
|
|
CCheckConsRowset::s_fMetadataInitialized = FALSE;
|
|
CCheckConsRowset::s_fSchemaSupported = FALSE;
|
|
CCheckConsRowset::s_fConsCatalogR = FALSE;
|
|
CCheckConsRowset::s_fConsSchemaR = FALSE;
|
|
CCheckConsRowset::s_fConsNameR = FALSE;
|
|
|
|
CPKRowset::s_fMetadataInitialized = FALSE;
|
|
CPKRowset::s_fSchemaSupported = FALSE;
|
|
CPKRowset::s_fTableCatalogR = FALSE;
|
|
CPKRowset::s_fTableSchemaR = FALSE;
|
|
CPKRowset::s_fTableNameR = FALSE;
|
|
|
|
CFKRowset::s_fMetadataInitialized = FALSE;
|
|
CFKRowset::s_fSchemaSupported = FALSE;
|
|
CFKRowset::s_fTableCatalogR = FALSE;
|
|
CFKRowset::s_fTableSchemaR = FALSE;
|
|
CFKRowset::s_fTableNameR = FALSE;
|
|
|
|
CKeyColumnUsageRowset::s_fMetadataInitialized = FALSE;
|
|
CKeyColumnUsageRowset::s_fSchemaSupported = FALSE;
|
|
CKeyColumnUsageRowset::s_fTableCatalogR = FALSE;
|
|
CKeyColumnUsageRowset::s_fTableSchemaR = FALSE;
|
|
CKeyColumnUsageRowset::s_fTableNameR = FALSE;
|
|
CKeyColumnUsageRowset::s_fConsCatalogR = FALSE;
|
|
CKeyColumnUsageRowset::s_fConsSchemaR = FALSE;
|
|
CKeyColumnUsageRowset::s_fConsNameR = FALSE;
|
|
|
|
return ModuleReleaseDBSession(pThisTestModule);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
// Given DBCOLUMNDESC, returns the Type name.
|
|
//--------------------------------------------------------------------------
|
|
WCHAR* GetColumnTypeName(DBCOLUMNDESC *pColumnDesc)
|
|
{
|
|
return pColumnDesc->pwszTypeName;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// release the property of all columns
|
|
//--------------------------------------------------------------------------
|
|
void ReleaseAllColumnPropSets(
|
|
DBCOLUMNDESC *rgColumnDesc, // [in] aray to be release
|
|
DBORDINAL cColumnDesc // [in] no of elementrs in the array
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
if ( (NULL == rgColumnDesc) ||
|
|
(0 == cColumnDesc))
|
|
return;
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
FreeProperties(&rgColumnDesc[i].cPropertySets, &rgColumnDesc[i].rgPropertySets);
|
|
ASSERT(0 == rgColumnDesc[i].cPropertySets);
|
|
ASSERT(NULL == rgColumnDesc[i].rgPropertySets);
|
|
}
|
|
} //ReleaseAllColumnPropSets
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Test Case Section
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @class Base Class
|
|
//
|
|
class TCITableDefinition : public CSessionObject {
|
|
protected:
|
|
// add critical section
|
|
CRITICAL_SECTION m_CriticalSection;
|
|
|
|
// used to check for residual tables
|
|
ULONG m_nTables;
|
|
|
|
// @cmember pointer to ITableDefinition interface
|
|
ITableDefinition *m_pITableDefinition;
|
|
ITableDefinitionWithConstraints *m_pITDWC;
|
|
BOOL m_fIsIDBInfo;
|
|
// @cmember list of CCol storing info about provider data types
|
|
CList <CCol, CCol&> m_ColList;
|
|
|
|
// @cmember data about table and column name
|
|
ULONG m_cMaxTableName, m_cMaxColName;
|
|
LPOLESTR m_pwszInvalidTableChars;
|
|
LPOLESTR m_pwszInvalidColChars;
|
|
|
|
// @cmember array of column descriptors on the table (limited operations on it)
|
|
DBCOLUMNDESC *m_rgColumnDesc;
|
|
DBORDINAL m_cColumnDesc;
|
|
|
|
// @cmembe aray of result for multithreading processing
|
|
HRESULT m_rgResult[nThreads];
|
|
// @cmember array of table name for multithreading
|
|
LPWSTR m_rgName[nThreads];
|
|
|
|
DBMATCHTYPE m_SupportedMatchType;
|
|
|
|
// @cmember Check the result and property status
|
|
BOOL CheckPropertyStatus(
|
|
GUID guidPropertySet, // [in] property set guid
|
|
GUID guidExpectedPS, // [in] expected prop set guid
|
|
DBPROP *pProp, // [in] property
|
|
HRESULT hr // [in] the result
|
|
);
|
|
|
|
// @cmember Check the prop status of a list of col desc
|
|
BOOL CheckColPropStatus(
|
|
DBORDINAL cColDesc, // [in]
|
|
DBCOLUMNDESC *rgColDesc, // [in] the size of the propset array
|
|
HRESULT hr // [in] the result of the previous op
|
|
);
|
|
|
|
|
|
// @cmember Drops the column and checks the result
|
|
HRESULT DropColumnAndCheck(
|
|
DBID *pTableID, // [in] the table ID
|
|
DBID *pColumnID, // [in] the ID of the column to be dropped
|
|
ITableDefinition *pITableDefinition = NULL, // [in] pointer to ITableDefinition interface
|
|
DBID *pBaseTableID = NULL // [in] if pTableID is exotic (e.g. fuly qualified) use this
|
|
);
|
|
|
|
// @cmember Drops the table and checks the result
|
|
HRESULT DropTableAndCheck(
|
|
DBID *pTableID, // [in] ID of the table to be dropped
|
|
ITableDefinition *pITableDefinition = NULL // [in] pointer to ITableDefinition interface
|
|
);
|
|
|
|
// @cmember Gets literal info about tables and columns
|
|
HRESULT GetLiteralInfo();
|
|
|
|
// @cmember Gets the catalog and schema name for a given table
|
|
BOOL GetCatalogSchemaNames(
|
|
LPWSTR pwszTableName, // [in] the name of the table
|
|
LPWSTR *ppwszCatalogName, // [out] catalog name
|
|
LPWSTR *ppwszSchemaName, // [out] schema name
|
|
CTable *pTable = NULL // [in] table object (DEFAULT NULL - use m_pTable)
|
|
);
|
|
|
|
// @cmember Check whether the array of ColumnDesc sent was preserved
|
|
// all the data should be inside, the only thing that is allowed to be modified <nl>
|
|
// is the property status
|
|
BOOL IsColumnDescPreserved
|
|
(
|
|
DBCOLUMNDESC *rgInColumnDesc, // the array passed to ITableDefinition
|
|
DBCOLUMNDESC *rgOutColumnDesc, // the aray returned by ITableDefinition
|
|
DBORDINAL cColumnDesc // the size of the arrays
|
|
);
|
|
|
|
// @cmember Build a valid table name of a certain length
|
|
WCHAR* BuildValidName(size_t, WCHAR*);
|
|
|
|
// @cmember Build an invalid table name of a certain length
|
|
WCHAR* BuildInvalidName(size_t, WCHAR*, WCHAR*);
|
|
|
|
// @cmember Uses m_pTable to get a column description mentioning all the provider types
|
|
void GetProviderTypes(void);
|
|
|
|
// @cmember Passes a type name and retrieves the column from m_ColList with info about that type
|
|
CCol GetType(WCHAR *pwszTypeName, DBTYPE wType, BOOL *fExists=NULL);
|
|
|
|
// @cmember Sets all the columns to maximum size as got from m_ColList (from PROVIDER_TYPES Rowset)
|
|
BOOL SetMaximumColSize(DBCOLUMNDESC*, DBORDINAL);
|
|
|
|
// @cmember Sets all the column sizes to 0
|
|
BOOL SetZeroColSize(DBCOLUMNDESC*, DBORDINAL);
|
|
|
|
// @cmember Set a default property in the property sets of a DBCOLUMNDESC
|
|
BOOL SetDefaultProperty(
|
|
DBPROPSET **prgPropertySets, // [in/out] array of property sets
|
|
ULONG *pcPropertySets, // [in/out] number of property sets
|
|
VARIANT *pvalue, // [in] property value
|
|
DBPROPOPTIONS dwOption = DBPROPOPTIONS_OPTIONAL, // [in] prop options
|
|
DBID colid = DB_NULLID, // [in] col id
|
|
GUID guidPropertySet = DBPROPSET_COLUMN, // [in] the GUID of the propset
|
|
ULONG *pcPropSet = NULL, // [out] index of property set
|
|
ULONG *pcProp =NULL // [out] index in the rgProperties array
|
|
);
|
|
|
|
// @cmember Compare the list of old columns against the list of new columns and the new column
|
|
BOOL CheckColInfo(DBCOLUMNDESC*, DBORDINAL, DBCOLUMNDESC*, DBORDINAL, DBCOLUMNDESC*);
|
|
|
|
// @cmember Compare the list of old columns against the list of new columns
|
|
BOOL AreColEqual(DBCOLUMNDESC*, DBORDINAL, DBCOLUMNDESC*, DBORDINAL);
|
|
|
|
// @cmember CheckReturnedDBID about the columns in the table
|
|
// pIndexID - [IN] the DBID asked for
|
|
// ppIndexID - [IN] the DBID created
|
|
BOOL CheckReturnedDBID(
|
|
DBID *pIndexID, // passed to CreateIndex
|
|
DBID **ppIndexID // returned by CreateIndex
|
|
);
|
|
|
|
// @member Add a column using ITableDefinition::AddColumn and check its addition
|
|
HRESULT AddColumnAndCheck(
|
|
DBID *pTableID, // [IN] table ID
|
|
DBCOLUMNDESC *pColumnDesc, // [IN] descriptor of the column to be added
|
|
DBID **ppColumnID, // [OUT] column ID for the resulted column
|
|
ITableDefinition *pITableDefinition = NULL, // [IN] pointer to ITableDefinition
|
|
DBID *pBaseTableID = NULL
|
|
);
|
|
|
|
// @member Check properties on rowseet and table
|
|
BOOL CheckRwstTblPropStatus(
|
|
ULONG cPropSet, // [in] the size of the propset array
|
|
DBPROPSET *rgPropSet, // [in] propset array
|
|
HRESULT hr // [in] the result of the previous op
|
|
);
|
|
|
|
// @member Create the table using ITableDefinition::CreateTable and check its creation
|
|
// then drops the table
|
|
HRESULT CCNDropTable(
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBORDINAL cColumnDescs, // [in] the number of columns to be created
|
|
DBCOLUMNDESC *rgColumnDesc, // [in/out] array of columns to be created
|
|
REFIID riid, // [in] rowset interface to be returned
|
|
ULONG cPropertySets, // [in] number of roset property sets asked
|
|
DBPROPSET *rgPropertySets, // [in/out] array of rowset property sets
|
|
BOOL fNullPPTableID = FALSE // [in] if TRUE ppTableID will be NULL
|
|
);
|
|
|
|
// @cmember Check whether the columns were properly created
|
|
// The columns of the m_pTable are checked against the column descriptor array <nl>
|
|
// returned by ITableDefinition::CreateTable method.
|
|
BOOL AreColumnsCreatedOK(
|
|
DBCOLUMNDESC *rgOutColumnDesc, // [in] the aray returned by ITableDefinition::CreateTable
|
|
DBORDINAL cColumnDesc, // [in] the size of the arrays
|
|
DBID *pTableID = NULL, // [in] Table ID of the table that is checked
|
|
IUnknown *pIUnknown = NULL // [in] pointer to a rowset interface on the table
|
|
);
|
|
|
|
|
|
// @cmember Check whether the property sets asked for rowset was preserved
|
|
// all the data should be inside, the only thing that is allowed to be modified <nl>
|
|
// is the property status
|
|
BOOL IsRowsetPropSetPreserved
|
|
(
|
|
DBPROPSET *rgInPropertySets, // the array passed to ITableDefinition::CreateTable
|
|
DBPROPSET *rgOutPropertysets, // the aray returned by ITableDefinition::CreateTable
|
|
ULONG cPropertySets // the size of the arrays
|
|
);
|
|
|
|
|
|
// @cmember Check whether the rowset properties were properly created
|
|
// The rowset properties of the m_pTable are checked against the property set<nl>
|
|
// returned by ITableDefinition::CreateTable method.
|
|
BOOL IsRowsetPropSetCreatedOK
|
|
(
|
|
DBPROPSET *rgOutPropertySets, // the aray returned by ITableDefinition::CreateTable
|
|
ULONG cPropertySets, // the size of the arrays
|
|
IUnknown *pIUnknown // pointer to rowset interface
|
|
);
|
|
|
|
|
|
// @cmember Creates a table with a column of each provider type and returns a rowset
|
|
// to the new created table. The rowset is created with the properties required and it
|
|
// is tested
|
|
BOOL CreateWithRowsetProps
|
|
(
|
|
ULONG nProperties, // number of the properties to be set
|
|
DBPROPID *rgPropID, // array with the propIDs
|
|
DBTYPE *rgDBType, // type of property values
|
|
LPVOID *rgValue, // values to be set
|
|
DBPROPOPTIONS *rgOptions, // options of properties
|
|
struct _GUID *pRIID // interface asked on rowset
|
|
);
|
|
|
|
|
|
// @cmember Creates a table with a column of each provider type and returns a rowset
|
|
// to the new created table. The rowset is created with the property required and it
|
|
// is tested
|
|
int CreateWithOneRowsetProps
|
|
(
|
|
DBPROPID PropID, // Property ID
|
|
DBTYPE DBType, // type of property value
|
|
LPVOID Value, // value to be set
|
|
struct _GUID *pRIID // interface asked on rowset
|
|
);
|
|
|
|
public:
|
|
|
|
HRESULT AddUniqueConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL ulCol,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
);
|
|
|
|
HRESULT AddUniqueConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL cCol,
|
|
DBORDINAL *rgCol,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
);
|
|
|
|
HRESULT AddPrimaryKeyConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL ulCol,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
);
|
|
|
|
HRESULT AddPrimaryKeyConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL cCol,
|
|
DBORDINAL *rgCol,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
);
|
|
|
|
HRESULT AddKeyConstraint(
|
|
DBCONSTRAINTTYPE ConstraintType,
|
|
CTable *pTable,
|
|
DBORDINAL cCol,
|
|
DBORDINAL *rgCol,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
);
|
|
|
|
HRESULT AddForeignKeyConstraint(
|
|
CTable *pBaseTable,
|
|
DBORDINAL cBaseCol,
|
|
DBORDINAL *rgBaseCol,
|
|
CTable *pReferencedTable,
|
|
DBORDINAL cReferencedCol,
|
|
DBORDINAL *rgReferencedCol,
|
|
DBMATCHTYPE MatchType,
|
|
DBUPDELRULE UpdateRule = DBUPDELRULE_NOACTION,
|
|
DBUPDELRULE DeleteRule = DBUPDELRULE_NOACTION,
|
|
DBDEFERRABILITY Deferrability = 0
|
|
);
|
|
|
|
ITableDefinition *pITableDefinition() {return m_pITableDefinition;}
|
|
ITableDefinitionWithConstraints *pITDWC() {return m_pITDWC;}
|
|
|
|
DBMATCHTYPE SupportedMatchType() {
|
|
return m_SupportedMatchType;
|
|
}
|
|
|
|
// @member Add a constraint to a table using ITableDefinitionWithConstraints::AddConstraint and check its creation
|
|
HRESULT AddConstraintAndCheck(
|
|
ITableDefinitionWithConstraints *pITableDefinitionWithConstraints, // [in] pointer to the ITableDefinitionWithConstraints interface to be used
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBCONSTRAINTDESC *pConstraintDescs, // [in] new constraint
|
|
BOOL fDifferentColTypesInFK = FALSE
|
|
);
|
|
|
|
// @member Drop a constraint to a table using ITableDefinitionWithConstraints::DropConstraint and check its deletion
|
|
HRESULT DropConstraintAndCheck(
|
|
ITableDefinitionWithConstraints *pITableDefinitionWithConstraints, // [in] pointer to the ITableDefinitionWithConstraints interface to be used
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBID *pConstraintID // [in] pointer to the DBID of the constraint
|
|
);
|
|
|
|
// @cmember Start a local transaction using the interface pointer passed
|
|
HRESULT StartTransaction(ITransactionLocal *pITransactionLocal);
|
|
|
|
// @cmember Fills in a variant with whatever it needs
|
|
BOOL FillVariant(VARIANT *pVariant);
|
|
|
|
// @cmember Builds a default value for a given column type
|
|
BOOL GetDefaultValue(
|
|
DBCOLUMNDESC *pColumnDesc, // [in] column for which the default is build
|
|
VARIANT *pVariant, // [out] variant that contains the default value
|
|
CTable *pTable=NULL // [in] CTable to use
|
|
);
|
|
|
|
// @cmember CompareColumnDesc
|
|
// check the new column (first parameter against the result of
|
|
BOOL CompareColumnDesc(DBCOLUMNDESC*, DBCOLUMNDESC*);
|
|
|
|
// @cmember Compare 2 columns got by GetColumnDescOnTable
|
|
BOOL AreColEqual(DBCOLUMNDESC*, DBCOLUMNDESC *);
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
virtual unsigned MyThreadProc(ULONG i) {return i;}
|
|
|
|
//constructor
|
|
TCITableDefinition(WCHAR *wstrTestCaseName);
|
|
|
|
// checks the interfaces on the object, as well as count reference and parent of the rowset
|
|
BOOL CheckRowset(IUnknown* pIRowset);
|
|
|
|
// @cmember GetInfo about the columns in the table
|
|
BOOL GetColumnInfo(DBID*, DBORDINAL*, DBCOLUMNINFO**, OLECHAR**);
|
|
|
|
// @cmember Get an array od Column Descriptors on a Table
|
|
BOOL GetColumnDescOnTable(DBID*, DBCOLUMNDESC**, DBORDINAL*);
|
|
|
|
//destructor
|
|
virtual ~TCITableDefinition(){;}
|
|
|
|
// @cmember Get the number of tables in a data sources, based on IDBSchemaRowset
|
|
ULONG GetNoOfTables();
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Insert |
|
|
// Inserts 1 row in table using IRowsetChange.
|
|
//
|
|
// @mfunc Insert
|
|
// @rdesc HRESULT indicating success or failure
|
|
// @flag S_OK | Function ran without problem
|
|
// @flag E_FAIL | No Columns Marked for use or SetNewData failed
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT Insert(
|
|
DBCOUNTITEM ulRowNumber, // @parm [IN] Row number to insert (0 for next)
|
|
IUnknown *pIUnknown, // @parm [IN] Pointer to rowset interface
|
|
ULONG cNulls = 0, // @parm [IN] Number of columns to be set to NULL
|
|
DBORDINAL *rgNulls = NULL, // @parm [IN] Array of columns to be set to NULL
|
|
CTable *pTable = NULL // @parm [IN] Table (DEFAULT NULL - use m_pTable)
|
|
);
|
|
|
|
// creates a table with not nullable column
|
|
HRESULT CreateTableWithNoNullableColumns(
|
|
CTable *pTable, // @param [IN] pointer to CTable
|
|
DBCOUNTITEM ulRowCount, // @parm [IN] # of Rows to insert into table, 1 based
|
|
DBORDINAL ulIndex = 0, // @parm [IN] Column Number of index, 1 based (Default=1)
|
|
WCHAR *pwszTableName = NULL, // @parm [IN] TableName, if NULL call MakeTableName() (Default=NULL)
|
|
EVALUE eValue = PRIMARY, // @parm [IN] Insert PRIMARY or SECONDARY data (Default=PRIMARY)
|
|
BOOL fFirstUpdateable = FALSE // @parm [IN] TRUE means first column will be autoinc (Default=FALSE)
|
|
);
|
|
|
|
// @member Create the table using ITableDefinition::CreateTable and check its creation
|
|
virtual HRESULT CreateAndCheckTable(
|
|
ITableDefinition *pITableDefinition, // [in] pointer to the ITableDefinition interface to be used
|
|
IUnknown *pUnkOuter, // [in] pointer to controlling unknown
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBORDINAL cColumnDescs, // [in] the number of columns to be created
|
|
DBCOLUMNDESC *rgColumnDescs, // [in/out] array of columns to be created
|
|
REFIID riid, // [in] rowset interface to be returned
|
|
ULONG cPropertySets, // [in] number of roset property sets asked
|
|
DBPROPSET *rgPropertySets, // [in/out] array of rowset property sets
|
|
DBID **ppTableID, // [out] returned table ID
|
|
IUnknown **ppRowset // [out] pointer to outer interface
|
|
);
|
|
|
|
// @member Create the table using ITableDefinitionWithConstraints::CreateTableWithConstraints and check its creation
|
|
HRESULT CreateAndCheckTableWithConstraints(
|
|
ITableDefinitionWithConstraints *pITableDefinitionWithConstraints, // [in] pointer to the ITableDefinitionWithConstraints interface to be used
|
|
IUnknown *pUnkOuter, // [in] pointer to controlling unknown
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBORDINAL cColumnDescs, // [in] the number of columns to be created
|
|
DBCOLUMNDESC *rgColumnDescs, // [in/out] array of columns to be created
|
|
ULONG cConstraintDescs, // [in] the number of constraints to be created
|
|
DBCONSTRAINTDESC *rgConstraintDescs, // [in/out] array of constraints
|
|
REFIID riid, // [in] rowset interface to be returned
|
|
ULONG cPropertySets, // [in] number of roset property sets asked
|
|
DBPROPSET *rgPropertySets, // [in/out] array of rowset property sets
|
|
DBID **ppTableID, // [out] returned table ID
|
|
IUnknown **ppRowset // [out] pointer to outer interface
|
|
);
|
|
|
|
// @cmember Set a property in the property sets of a DBCOLUMNDESC
|
|
BOOL SetProperty(
|
|
DBPROPSET **prgPropertySets, // [in/out] array of property sets
|
|
ULONG *pcPropertySets, // [in/out] number of property sets
|
|
DBPROPID propID, // [in] property ID
|
|
DBTYPE wType, // [in] value type
|
|
LPVOID value, // [in] property value
|
|
DBPROPOPTIONS dwOption = DBPROPOPTIONS_OPTIONAL, // [in] prop options
|
|
DBID colid = DB_NULLID, // [in] col id
|
|
GUID guidPropertySet = DBPROPSET_COLUMN, // [in] the GUID of the propset
|
|
ULONG *pcPropSet = NULL, // [out] index of property set
|
|
ULONG *pcProp =NULL // [out] index in the rgProperties array
|
|
);
|
|
|
|
};
|
|
|
|
|
|
class CLimitTable {
|
|
|
|
IDBSchemaRowset *m_pIDBSchemaRowset;
|
|
ITableDefinitionWithConstraints *m_pITDWC;
|
|
DBCOUNTITEM m_IndexColSize,
|
|
m_IndexNullable,
|
|
m_IndexLong,
|
|
m_IndexFixedLength,
|
|
m_IndexDataType,
|
|
m_IndexTypeName;
|
|
|
|
// Selected column specs
|
|
DBLENGTH m_cSelectedColSize;
|
|
DBTYPE m_dbtSelectedCol;
|
|
WCHAR *m_pwszSelectedCol;
|
|
|
|
HRESULT Init();
|
|
|
|
HRESULT GetBestType();
|
|
HRESULT FindIndexes(IRowset *pIRowset);
|
|
HRESULT CreateTable(DBCOUNTITEM cTotalCol, DBID **ppTableID);
|
|
|
|
HRESULT CreatePrimaryKey(DBID *pTableID, DBCOUNTITEM cTotalCols);
|
|
HRESULT CreateUniqueKey(DBID *pTableID, DBCOUNTITEM cTotalCols);
|
|
HRESULT CreateForeignKey(DBID *pBaseID, DBID *pRefID, DBCOUNTITEM cTotalCols);
|
|
|
|
public:
|
|
CLimitTable();
|
|
~CLimitTable();
|
|
|
|
HRESULT CheckPrimaryKeyLimit();
|
|
HRESULT CheckUniqueKeyLimit();
|
|
HRESULT CheckForeignKeyLimit();
|
|
|
|
HRESULT DropTable(DBID *pTableID);
|
|
};
|
|
|
|
|
|
CLimitTable::CLimitTable() {
|
|
m_pIDBSchemaRowset = NULL;
|
|
m_pITDWC = NULL;
|
|
|
|
m_IndexColSize = -1;
|
|
m_IndexNullable = -1;
|
|
m_IndexLong = -1;
|
|
m_IndexFixedLength = -1;
|
|
m_IndexDataType = -1;
|
|
m_IndexTypeName = -1;
|
|
|
|
m_cSelectedColSize = ULONG_MAX;
|
|
m_dbtSelectedCol = -1;
|
|
m_pwszSelectedCol = NULL;
|
|
}
|
|
|
|
CLimitTable::~CLimitTable() {
|
|
PROVIDER_FREE(m_pwszSelectedCol);
|
|
|
|
SAFE_RELEASE(m_pITDWC);
|
|
SAFE_RELEASE(m_pIDBSchemaRowset);
|
|
}
|
|
|
|
HRESULT CLimitTable::Init() {
|
|
TBEGIN
|
|
|
|
ULONG ulTotalSchemas = 0,
|
|
i;
|
|
GUID *rgSchemas = NULL;
|
|
ULONG *rgRestrictions = NULL;
|
|
bool fResult = false;
|
|
|
|
// init varaibles
|
|
m_IndexColSize = -1;
|
|
m_IndexNullable = -1;
|
|
m_IndexLong = -1;
|
|
m_IndexFixedLength = -1;
|
|
m_IndexDataType = -1;
|
|
m_IndexTypeName = -1;
|
|
|
|
m_cSelectedColSize = ULONG_MAX;
|
|
m_dbtSelectedCol = -1;
|
|
|
|
PROVIDER_FREE(m_pwszSelectedCol);
|
|
|
|
SAFE_RELEASE(m_pITDWC);
|
|
SAFE_RELEASE(m_pIDBSchemaRowset);
|
|
|
|
// Verify that IDBSchemaRowset is supported
|
|
TESTC_PROVIDER(VerifyInterface(GetModInfo()->GetThisTestModule()->m_pIUnknown2, IID_IDBSchemaRowset,
|
|
SESSION_INTERFACE, (IUnknown**) &m_pIDBSchemaRowset));
|
|
|
|
// Verify that ITableDefinitionWithConstraints is supported
|
|
TESTC_PROVIDER(VerifyInterface(GetModInfo()->GetThisTestModule()->m_pIUnknown2, IID_ITableDefinitionWithConstraints,
|
|
SESSION_INTERFACE, (IUnknown**) &m_pITDWC));
|
|
|
|
// Now check if DBSCHEMA_PROVIDER_TYPES is supported
|
|
TESTC_(m_pIDBSchemaRowset->GetSchemas(&ulTotalSchemas, &rgSchemas, &rgRestrictions), S_OK);
|
|
|
|
fResult = false;
|
|
for(i = 0; i < ulTotalSchemas; i++)
|
|
if (rgSchemas[i] == DBSCHEMA_PROVIDER_TYPES)
|
|
fResult = true;
|
|
TESTC(fResult);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgSchemas);
|
|
PROVIDER_FREE(rgRestrictions);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
HRESULT CLimitTable::FindIndexes(IRowset *pIRowset) {
|
|
TBEGIN
|
|
|
|
IColumnsInfo *pIColInfo = NULL;
|
|
DBORDINAL cTotalCols = 0;
|
|
DBCOLUMNINFO *rgColInfo = NULL;
|
|
OLECHAR *pwszBuffer = NULL;
|
|
ULONG i;
|
|
|
|
TESTC(pIRowset!=NULL);
|
|
TESTC_(pIRowset->QueryInterface(IID_IColumnsInfo, (void**) &pIColInfo), S_OK);
|
|
TESTC_(pIColInfo->GetColumnInfo(&cTotalCols, &rgColInfo, &pwszBuffer), S_OK);
|
|
|
|
for(i=0;i<cTotalCols;i++) {
|
|
if (!wcscmp(rgColInfo[i].pwszName, L"COLUMN_SIZE"))
|
|
m_IndexColSize = i;
|
|
else if (!wcscmp(rgColInfo[i].pwszName, L"IS_NULLABLE"))
|
|
m_IndexNullable = i;
|
|
else if (!wcscmp(rgColInfo[i].pwszName, L"IS_LONG"))
|
|
m_IndexLong = i;
|
|
else if (!wcscmp(rgColInfo[i].pwszName, L"IS_FIXEDLENGTH"))
|
|
m_IndexFixedLength = i;
|
|
else if (!wcscmp(rgColInfo[i].pwszName, L"DATA_TYPE"))
|
|
m_IndexDataType = i;
|
|
else if (!wcscmp(rgColInfo[i].pwszName, L"TYPE_NAME"))
|
|
m_IndexTypeName = i;
|
|
}
|
|
|
|
TESTC(m_IndexColSize!=-1 && m_IndexNullable!=-1 && m_IndexLong!=-1 && m_IndexFixedLength!=-1 &&
|
|
m_IndexDataType!=-1 && m_IndexTypeName!=-1);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(pwszBuffer);
|
|
PROVIDER_FREE(rgColInfo);
|
|
SAFE_RELEASE(pIColInfo);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
HRESULT CLimitTable::GetBestType() {
|
|
TBEGIN
|
|
IRowset *pIRowset = NULL;
|
|
IAccessor *pIAccessor = NULL;
|
|
HACCESSOR hAccessor = NULL;
|
|
DBBINDING *rgBindings = NULL;
|
|
DBCOUNTITEM cBindings = 0,
|
|
cRowSize = 0;
|
|
HROW *phRows = NULL;
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
char *pszRowData = NULL;
|
|
bool fResult = false,
|
|
IsSQLServer7 = false;
|
|
WCHAR *pwszVer = NULL;
|
|
CLSID clsidSQL;
|
|
|
|
TESTC(m_pIDBSchemaRowset && m_pITDWC);
|
|
|
|
// Hack for SQL Server 7.0 which doesnt allow keys on BIT data type but provides
|
|
// no way to determine this behavior.
|
|
TESTC_(CLSIDFromProgID(L"SQLOLEDB", &clsidSQL), S_OK);
|
|
|
|
if (PROVIDER_CLSID == clsidSQL) {
|
|
if (::SupportedProperty(DBPROP_DBMSVER, DBPROPSET_DATASOURCEINFO,
|
|
GetModInfo()->GetThisTestModule()->m_pIUnknown)) {
|
|
|
|
TESTC(::GetProperty(DBPROP_DBMSVER, DBPROPSET_DATASOURCEINFO,
|
|
GetModInfo()->GetThisTestModule()->m_pIUnknown,
|
|
&pwszVer));
|
|
|
|
if (wcscmp(pwszVer, L"08.00.0000")<0)
|
|
IsSQLServer7 = true;
|
|
}
|
|
|
|
}
|
|
|
|
// Get provider types rowset
|
|
TESTC_(m_pIDBSchemaRowset->GetRowset(NULL, DBSCHEMA_PROVIDER_TYPES, 0, NULL,
|
|
IID_IRowset, 0, NULL, (IUnknown**) &pIRowset), S_OK);
|
|
|
|
// find indexes to different columns
|
|
TESTC(FindIndexes(pIRowset));
|
|
|
|
// get accessor
|
|
TESTC(VerifyInterface(pIRowset, IID_IAccessor, ROWSET_INTERFACE, (IUnknown**)&pIAccessor));
|
|
|
|
// Create accessor
|
|
TESTC_(GetAccessorAndBindings(pIRowset, DBACCESSOR_ROWDATA, &hAccessor,
|
|
&rgBindings, &cBindings, &cRowSize, DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH,
|
|
ALL_COLS_BOUND, FORWARD, NO_COLS_BY_REF, NULL, NULL,
|
|
NULL, DBTYPE_EMPTY, 0, NULL), S_OK);
|
|
|
|
// Now get data and find best matching row
|
|
pszRowData = (char*) PROVIDER_ALLOC(cRowSize);
|
|
fResult = false;
|
|
|
|
while(pIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &phRows)==S_OK) {
|
|
pIRowset->GetData(phRows[0], hAccessor, pszRowData);
|
|
|
|
if (*(VARIANT_BOOL*)&pszRowData[rgBindings[m_IndexNullable].obValue] == VARIANT_TRUE &&
|
|
*(VARIANT_BOOL*)&pszRowData[rgBindings[m_IndexLong].obValue] == VARIANT_FALSE &&
|
|
*(VARIANT_BOOL*)&pszRowData[rgBindings[m_IndexFixedLength].obValue] == VARIANT_TRUE &&
|
|
|
|
!(IsSQLServer7 && !wcscmp((WCHAR*)&pszRowData[rgBindings[m_IndexTypeName].obValue], L"bit"))
|
|
) {
|
|
|
|
if (*(DWORD*)&pszRowData[rgBindings[m_IndexColSize].obValue] < m_cSelectedColSize) {
|
|
|
|
m_cSelectedColSize = *(DWORD*)&pszRowData[rgBindings[m_IndexColSize].obValue];
|
|
m_dbtSelectedCol = *(WORD*) &pszRowData[rgBindings[m_IndexDataType].obValue];
|
|
PROVIDER_FREE(m_pwszSelectedCol);
|
|
m_pwszSelectedCol = wcsDuplicate((WCHAR*) &pszRowData[rgBindings[m_IndexTypeName].obValue]);
|
|
fResult = true;
|
|
}
|
|
}
|
|
|
|
TESTC_(pIRowset->ReleaseRows(1, phRows, NULL, NULL, NULL), S_OK)
|
|
PROVIDER_FREE(phRows);
|
|
cRowsObtained = 0;
|
|
}
|
|
|
|
TESTC(fResult);
|
|
|
|
odtLog << "Using '" << m_pwszSelectedCol << "' data type to find maximum limit\n";
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgBindings);
|
|
PROVIDER_FREE(pszRowData);
|
|
PROVIDER_FREE(pwszVer);
|
|
if (hAccessor && pIAccessor)
|
|
pIAccessor->ReleaseAccessor(hAccessor, NULL);
|
|
|
|
SAFE_RELEASE(pIAccessor);
|
|
SAFE_RELEASE(pIRowset);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
HRESULT CLimitTable::CreateTable(DBCOUNTITEM cTotalCol, DBID **ppTableID) {
|
|
TBEGIN
|
|
|
|
DBCOLUMNDESC *rgColDesc = NULL;
|
|
DBCOUNTITEM i;
|
|
WCHAR *pwszColName = NULL;
|
|
IRowset *pIRowset = NULL;
|
|
DBID *pid = NULL;
|
|
DBPROPSET PropSet;
|
|
DBPROP Prop;
|
|
|
|
rgColDesc = (DBCOLUMNDESC*) PROVIDER_ALLOC(cTotalCol * sizeof(DBCOLUMNDESC));
|
|
pwszColName = (WCHAR*) PROVIDER_ALLOC(1024);
|
|
|
|
Prop.dwPropertyID = DBPROP_COL_NULLABLE;
|
|
Prop.dwOptions = DBPROPOPTIONS_REQUIRED;
|
|
Prop.dwStatus = DBPROPSTATUS_OK;
|
|
Prop.colid = DB_NULLID;
|
|
VariantInit(&Prop.vValue);
|
|
V_VT(&Prop.vValue) = VT_BOOL;
|
|
V_BOOL(&Prop.vValue) = VARIANT_FALSE;
|
|
|
|
PropSet.guidPropertySet = DBPROPSET_COLUMN;
|
|
PropSet.cProperties = 1;
|
|
PropSet.rgProperties = &Prop;
|
|
|
|
// Create Column Description structure
|
|
for (i=0; i<cTotalCol; i++) {
|
|
swprintf(pwszColName, L"Col%d", i);
|
|
rgColDesc[i].pwszTypeName = m_pwszSelectedCol;
|
|
rgColDesc[i].pTypeInfo = NULL;
|
|
rgColDesc[i].rgPropertySets = &PropSet; //NULL;
|
|
rgColDesc[i].pclsid = NULL;
|
|
rgColDesc[i].cPropertySets = 1; //0;
|
|
rgColDesc[i].ulColumnSize = m_cSelectedColSize;
|
|
rgColDesc[i].dbcid.eKind = DBKIND_NAME;
|
|
rgColDesc[i].dbcid.uName.pwszName = wcsDuplicate(pwszColName);
|
|
rgColDesc[i].bPrecision = 0;
|
|
rgColDesc[i].bScale = 0;
|
|
}
|
|
|
|
|
|
// Now create table
|
|
TESTC_(m_pITDWC->CreateTable(NULL, NULL, cTotalCol,
|
|
rgColDesc, IID_IRowset, 0, NULL,
|
|
&pid, (IUnknown**) &pIRowset), S_OK);
|
|
|
|
*ppTableID = pid;
|
|
for(i=0;i < cTotalCol; i++)
|
|
PROVIDER_FREE(rgColDesc[i].dbcid.uName.pwszName);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(pwszColName);
|
|
PROVIDER_FREE(rgColDesc);
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
HRESULT CLimitTable::CreatePrimaryKey(DBID *pTableID, DBCOUNTITEM cTotalCols) {
|
|
|
|
DBID *pPKDBID = NULL;
|
|
DBCOUNTITEM i;
|
|
WCHAR *pwszColName = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
DBCONSTRAINTDESC Cons;
|
|
DBID ConsID;
|
|
|
|
ASSERT(pTableID && cTotalCols > 0);
|
|
pwszColName = (WCHAR*) PROVIDER_ALLOC(1024);
|
|
|
|
// Build PK columns list
|
|
pPKDBID = (DBID*) PROVIDER_ALLOC(sizeof(DBID) * cTotalCols);
|
|
for(i=0; i<cTotalCols; i++) {
|
|
swprintf(pwszColName, L"Col%d", i);
|
|
pPKDBID[i].eKind = DBKIND_NAME;
|
|
pPKDBID[i].uName.pwszName = wcsDuplicate(pwszColName);
|
|
}
|
|
|
|
// Build constraint DBID
|
|
ConsID.eKind = DBKIND_NAME;
|
|
ConsID.uName.pwszName = L"PKConstraint";
|
|
|
|
// Build constraint structure
|
|
Cons.pConstraintID = &ConsID;
|
|
Cons.ConstraintType = DBCONSTRAINTTYPE_PRIMARYKEY;
|
|
Cons.cColumns = cTotalCols;
|
|
Cons.rgColumnList = pPKDBID;
|
|
Cons.pReferencedTableID = NULL;
|
|
Cons.cForeignKeyColumns = 0;
|
|
Cons.rgForeignKeyColumnList = NULL;
|
|
Cons.pwszConstraintText = NULL;
|
|
Cons.cReserved = 0;
|
|
Cons.rgReserved = NULL;
|
|
Cons.Deferrability = 0;
|
|
|
|
hr = m_pITDWC->AddConstraint(pTableID, &Cons);
|
|
|
|
for(i=0; i<cTotalCols; i++)
|
|
PROVIDER_FREE(pPKDBID[i].uName.pwszName);
|
|
PROVIDER_FREE(pPKDBID);
|
|
PROVIDER_FREE(pwszColName);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CLimitTable::CreateUniqueKey(DBID *pTableID, DBCOUNTITEM cTotalCols) {
|
|
|
|
DBID *pPKDBID = NULL;
|
|
DBCOUNTITEM i;
|
|
WCHAR *pwszColName = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
DBCONSTRAINTDESC Cons;
|
|
DBID ConsID;
|
|
|
|
ASSERT(pTableID && cTotalCols > 0);
|
|
pwszColName = (WCHAR*) PROVIDER_ALLOC(1024);
|
|
|
|
// Build PK columns list
|
|
pPKDBID = (DBID*) PROVIDER_ALLOC(sizeof(DBID) * cTotalCols);
|
|
for(i=0; i<cTotalCols; i++) {
|
|
swprintf(pwszColName, L"Col%d", i);
|
|
pPKDBID[i].eKind = DBKIND_NAME;
|
|
pPKDBID[i].uName.pwszName = wcsDuplicate(pwszColName);
|
|
}
|
|
|
|
// Build constraint DBID
|
|
ConsID.eKind = DBKIND_NAME;
|
|
ConsID.uName.pwszName = L"UniqueConstraint";
|
|
|
|
// Build constraint structure
|
|
Cons.pConstraintID = &ConsID;
|
|
Cons.ConstraintType = DBCONSTRAINTTYPE_UNIQUE;
|
|
Cons.cColumns = cTotalCols;
|
|
Cons.rgColumnList = pPKDBID;
|
|
Cons.pReferencedTableID = NULL;
|
|
Cons.cForeignKeyColumns = 0;
|
|
Cons.rgForeignKeyColumnList = NULL;
|
|
Cons.pwszConstraintText = NULL;
|
|
Cons.cReserved = 0;
|
|
Cons.rgReserved = NULL;
|
|
Cons.Deferrability = 0;
|
|
|
|
hr = m_pITDWC->AddConstraint(pTableID, &Cons);
|
|
|
|
for(i=0; i<cTotalCols; i++)
|
|
PROVIDER_FREE(pPKDBID[i].uName.pwszName);
|
|
PROVIDER_FREE(pPKDBID);
|
|
PROVIDER_FREE(pwszColName);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CLimitTable::CreateForeignKey(DBID *pBaseID, DBID *pRefID, DBCOUNTITEM cTotalCols) {
|
|
DBID *pPKDBID = NULL,
|
|
*pFKDBID = NULL;
|
|
DBCOUNTITEM i;
|
|
WCHAR *pwszColName = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
DBCONSTRAINTDESC Cons;
|
|
DBID ConsID;
|
|
|
|
ASSERT(pBaseID && pRefID && cTotalCols > 0);
|
|
pwszColName = (WCHAR*) PROVIDER_ALLOC(1024);
|
|
|
|
// Build PK columns list
|
|
pPKDBID = (DBID*) PROVIDER_ALLOC(sizeof(DBID) * cTotalCols);
|
|
for(i=0; i<cTotalCols; i++) {
|
|
swprintf(pwszColName, L"Col%d", i);
|
|
pPKDBID[i].eKind = DBKIND_NAME;
|
|
pPKDBID[i].uName.pwszName = wcsDuplicate(pwszColName);
|
|
}
|
|
|
|
// Build FK columns list
|
|
pFKDBID = (DBID*) PROVIDER_ALLOC(sizeof(DBID) * cTotalCols);
|
|
for(i=0; i<cTotalCols; i++) {
|
|
swprintf(pwszColName, L"Col%d", i);
|
|
pFKDBID[i].eKind = DBKIND_NAME;
|
|
pFKDBID[i].uName.pwszName = wcsDuplicate(pwszColName);
|
|
}
|
|
|
|
|
|
// Build constraint DBID
|
|
ConsID.eKind = DBKIND_NAME;
|
|
ConsID.uName.pwszName = L"FKConstraint";
|
|
|
|
// Build constraint structure
|
|
Cons.pConstraintID = &ConsID;
|
|
Cons.ConstraintType = DBCONSTRAINTTYPE_FOREIGNKEY;
|
|
Cons.cColumns = cTotalCols;
|
|
Cons.rgColumnList = pPKDBID;
|
|
Cons.pReferencedTableID = pRefID;
|
|
Cons.cForeignKeyColumns = cTotalCols;
|
|
Cons.rgForeignKeyColumnList = pFKDBID;
|
|
Cons.pwszConstraintText = NULL;
|
|
Cons.cReserved = 0;
|
|
Cons.rgReserved = NULL;
|
|
Cons.Deferrability = 0;
|
|
Cons.UpdateRule = DBUPDELRULE_NOACTION;
|
|
Cons.DeleteRule = DBUPDELRULE_NOACTION;
|
|
Cons.MatchType = DBMATCHTYPE_NONE;
|
|
|
|
TESTC_(hr = m_pITDWC->AddConstraint(pBaseID, &Cons), S_OK);
|
|
|
|
for(i=0; i<cTotalCols; i++) {
|
|
PROVIDER_FREE(pPKDBID[i].uName.pwszName);
|
|
PROVIDER_FREE(pFKDBID[i].uName.pwszName);
|
|
}
|
|
|
|
PROVIDER_FREE(pPKDBID);
|
|
PROVIDER_FREE(pFKDBID);
|
|
|
|
PROVIDER_FREE(pwszColName);
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
HRESULT CLimitTable::CheckPrimaryKeyLimit() {
|
|
TBEGIN
|
|
|
|
DBID *pTableID = NULL;
|
|
DBCOUNTITEM i = 0;
|
|
HRESULT hr = S_OK;
|
|
// Initialize everything
|
|
TESTC(Init());
|
|
|
|
// Get provider types to be used in testing
|
|
TESTC(GetBestType());
|
|
|
|
// find the limit
|
|
for(i = 1; i <= 256; i++) {
|
|
TESTC(CreateTable(i, &pTableID));
|
|
hr = CreatePrimaryKey(pTableID, i);
|
|
TESTC(DropTable(pTableID));
|
|
|
|
if (FAILED(hr)) {
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
i--;
|
|
odtLog << "Maximum columns in Primary Key allowed: " << i << "\n";
|
|
TESTC(i != 0);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CLimitTable::CheckUniqueKeyLimit() {
|
|
TBEGIN
|
|
|
|
DBID *pTableID = NULL;
|
|
DBCOUNTITEM i = 0;
|
|
HRESULT hr = S_OK;
|
|
// Initialize everything
|
|
TESTC(Init());
|
|
|
|
// Get provider types to be used in testing
|
|
TESTC(GetBestType());
|
|
|
|
// find the limit
|
|
for(i = 1; i <= 256; i++) {
|
|
TESTC(CreateTable(i, &pTableID));
|
|
hr = CreateUniqueKey(pTableID, i);
|
|
TESTC(DropTable(pTableID));
|
|
|
|
if (FAILED(hr)) {
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
i--;
|
|
odtLog << "Maximum columns in Unique Key allowed: " << i << "\n";
|
|
TESTC(i != 0);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CLimitTable::CheckForeignKeyLimit() {
|
|
TBEGIN
|
|
|
|
DBID *pBaseID = NULL,
|
|
*pRefID = NULL;
|
|
DBCOUNTITEM i = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
// Initialize everything
|
|
TESTC(Init());
|
|
|
|
// Get provider types to be used in testing
|
|
TESTC(GetBestType());
|
|
|
|
// find the limit
|
|
for(i = 1; i <= 256; i++) {
|
|
TESTC(CreateTable(i, &pBaseID));
|
|
TESTC(CreateTable(i, &pRefID));
|
|
|
|
hr = CreatePrimaryKey(pBaseID, i);
|
|
if (SUCCEEDED(hr)) {
|
|
hr = CreateUniqueKey(pRefID, i);
|
|
if (SUCCEEDED(hr)) {
|
|
hr = CreateForeignKey(pBaseID, pRefID, i);
|
|
}
|
|
}
|
|
TESTC(DropTable(pBaseID));
|
|
TESTC(DropTable(pRefID));
|
|
|
|
PROVIDER_FREE(pBaseID);
|
|
PROVIDER_FREE(pRefID);
|
|
|
|
if (FAILED(hr)) {
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
i--;
|
|
odtLog << "Maximum columns in Foreign Key allowed: " << i << "\n";
|
|
TESTC(i != 0);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CLimitTable::DropTable(DBID *pTableID)
|
|
{
|
|
TBEGIN
|
|
|
|
TESTC(m_pITDWC != NULL);
|
|
TESTC_(m_pITDWC->DropTable(pTableID), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAddColumn)
|
|
//--------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinition::AddColumn
|
|
//
|
|
class TCAddColumn : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAddColumn,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Table doesn't exist => DB_E_NOTABLE
|
|
int Variation_1();
|
|
// @cmember The table is in use => DB_E_TABLEINUSE
|
|
int Variation_2();
|
|
// @cmember *pTableID = DB_NULLID => DB_E_NOTABLE
|
|
int Variation_3();
|
|
// @cmember pTableID = NULL => E_INVALIDARG
|
|
int Variation_4();
|
|
// @cmember Maximum length for table name => S_OK
|
|
int Variation_5();
|
|
// @cmember the table name is 1 char too long => DB_E_NOTABLE
|
|
int Variation_6();
|
|
// @cmember invalid table name => DB_E_NOTABLE
|
|
int Variation_7();
|
|
// @cmember pColumnDesc->dbcid = DB_NULLID
|
|
int Variation_8();
|
|
// @cmember Column name pointer is NULL => DB_E_BADCOLUMNID
|
|
int Variation_9();
|
|
// @cmember column name is an empty string => DB_E_BADCOLUMNID
|
|
int Variation_10();
|
|
// @cmember Maximum length of column name => S_OK
|
|
int Variation_11();
|
|
// @cmember 1-char-too-long column name => DB_E_BADCOLUMNID
|
|
int Variation_12();
|
|
// @cmember Add a column for each provider type, maximum column size => S_OK
|
|
int Variation_13();
|
|
// @cmember Add a column for each known type; ulColumnsize == 0 => S_OK
|
|
int Variation_14();
|
|
// @cmember Add a column for each provider type (table is populated) => S_OK
|
|
int Variation_15();
|
|
// @cmember Precision testing
|
|
int Variation_16();
|
|
// @cmember Scale testing
|
|
int Variation_17();
|
|
// @cmember Invalid value for the property of a column => DB_E_ERRORSOCCURRED
|
|
int Variation_18();
|
|
// @cmember Non-column property => DBPROPSTATUS_NOTSUPPORTED
|
|
int Variation_19();
|
|
// @cmember Inexistent property => DBPROPSTATUS_NOTSUPPORTED
|
|
int Variation_20();
|
|
// @cmember Bad option => DBPROPSTATUS_BADOPTION
|
|
int Variation_21();
|
|
// @cmember Conflicting property => DBPROPSTATUS_CONFLICTING
|
|
int Variation_22();
|
|
// @cmember Bad column ID for a property => ignored
|
|
int Variation_23();
|
|
// @cmember Bad column type (wType in DBCOLUMNDESC)
|
|
int Variation_24();
|
|
// @cmember Invalid provider type name for a column => DB_E_BADTYPE
|
|
int Variation_25();
|
|
// @cmember NULL ppColumnDesc => S_OK
|
|
int Variation_26();
|
|
// @cmember Autoincrementable column - DBPROP_COL_AUTOINCREMENT
|
|
int Variation_27();
|
|
// @cmember DBPROP_COL_DEFAULT
|
|
int Variation_28();
|
|
// @cmember DBPROP_COL_DESCRIPTION
|
|
int Variation_29();
|
|
// @cmember DBPROP_COL_FIXEDLENGTH
|
|
int Variation_30();
|
|
// @cmember DBPROP_COL_NULLABLE
|
|
int Variation_31();
|
|
// @cmember DBPROP_PRIMARYKEY
|
|
int Variation_32();
|
|
// @cmember DBPROP_COL_UNIQUE
|
|
int Variation_33();
|
|
// @cmember Duplicate an existing column => DB_E_DUPLCATECOLUMNID
|
|
int Variation_34();
|
|
// @cmember Abort retaining
|
|
int Variation_35();
|
|
// @cmember Abort without retaining
|
|
int Variation_36();
|
|
// @cmember Commit with retain
|
|
int Variation_37();
|
|
// @cmember Commit without retain
|
|
int Variation_38();
|
|
// @cmember Add a column for each provider type in an empty table => S_OK
|
|
int Variation_39();
|
|
// @cmember Add a column to a table created with a SQL command => S_OK
|
|
int Variation_40();
|
|
// @cmember Drop all the column of a table (via SQL stmt) and then try to add a column => S_OK
|
|
int Variation_41();
|
|
// @cmember Non NULL pTypeInfo in DBCOLUMNDESC => DB_E_BADTYPE
|
|
int Variation_42();
|
|
// @cmember Missmatch between wType and pwszTypeName => DB_E_BADTYPE
|
|
int Variation_43();
|
|
// @cmember Add a not nullable column and try to insert a null value for it
|
|
int Variation_44();
|
|
// @cmember Add a column on a view
|
|
int Variation_45();
|
|
// @cmember eKind != DBKIND_NAME for a column
|
|
int Variation_46();
|
|
// @cmember threads with different column
|
|
int Variation_47();
|
|
// @cmember threads on the same column
|
|
int Variation_48();
|
|
// @cmember add columns of alll known wType => S_OK
|
|
int Variation_49();
|
|
// @cmember Fully Qualified table name
|
|
int Variation_50();
|
|
// @cmember Quoted Table Name
|
|
int Variation_51();
|
|
// @cmember pColumnDesc == NULL => E_INVALIDARG
|
|
int Variation_52();
|
|
// @cmember cPropertySets != 0 and rgPropertySets == NULL in pColumnDesc => E_INVALIDARG
|
|
int Variation_53();
|
|
// @cmember cPropertySets == 0 and rgPropertySets != NULL in pColumnDesc => S_OK
|
|
int Variation_54();
|
|
// @cmember cProperties == 0 and rgProperties != NULL in pColumnDesc's propset => S_OK
|
|
int Variation_55();
|
|
// @cmember cProperties != 0 and rgProperties == NULL in pColumnDesc's propset => E_INVALIDARG
|
|
int Variation_56();
|
|
// @cmember pclsid not null
|
|
int Variation_57();
|
|
// @cmember NULL pwszTypeName => S_OK
|
|
int Variation_58();
|
|
// }} TCW_TESTVARS_END
|
|
|
|
unsigned MyThreadProc(ULONG i);
|
|
};
|
|
// {{ TCW_TESTCASE(TCAddColumn)
|
|
#define THE_CLASS TCAddColumn
|
|
BEG_TEST_CASE(TCAddColumn, TCITableDefinition, L"Testcase for ITableDefinition::AddColumn")
|
|
TEST_VARIATION(1, L"Table doesn't exist => DB_E_NOTABLE")
|
|
TEST_VARIATION(2, L"The table is in use => DB_E_TABLEINUSE")
|
|
TEST_VARIATION(3, L"*pTableID = DB_NULLID => DB_E_NOTABLE")
|
|
TEST_VARIATION(4, L"pTableID = NULL => E_INVALIDARG")
|
|
TEST_VARIATION(5, L"Maximum length for table name => S_OK")
|
|
TEST_VARIATION(6, L"the table name is 1 char too long => DB_E_NOTABLE")
|
|
TEST_VARIATION(7, L"invalid table name => DB_E_NOTABLE")
|
|
TEST_VARIATION(8, L"pColumnDesc->dbcid = DB_NULLID")
|
|
TEST_VARIATION(9, L"Column name pointer is NULL => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(10, L"column name is an empty string => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(11, L"Maximum length of column name => S_OK")
|
|
TEST_VARIATION(12, L"1-char-too-long column name => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(13, L"Add a column for each provider type, maximum column size => S_OK")
|
|
TEST_VARIATION(14, L"Add a column for each known type; ulColumnsize == 0 => S_OK")
|
|
TEST_VARIATION(15, L"Add a column for each provider type (table is populated) => S_OK")
|
|
TEST_VARIATION(16, L"Precision testing")
|
|
TEST_VARIATION(17, L"Scale testing")
|
|
TEST_VARIATION(18, L"Invalid value for the property of a column => DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(19, L"Non-column property => DBPROPSTATUS_NOTSUPPORTED")
|
|
TEST_VARIATION(20, L"Inexistent property => DBPROPSTATUS_NOTSUPPORTED")
|
|
TEST_VARIATION(21, L"Bad option => DBPROPSTATUS_BADOPTION")
|
|
TEST_VARIATION(22, L"Conflicting property => DBPROPSTATUS_CONFLICTING")
|
|
TEST_VARIATION(23, L"Bad column ID for a property => ignored")
|
|
TEST_VARIATION(24, L"Bad column type (wType in DBCOLUMNDESC)")
|
|
TEST_VARIATION(25, L"Invalid provider type name for a column => DB_E_BADTYPE")
|
|
TEST_VARIATION(26, L"NULL ppColumnDesc => S_OK")
|
|
TEST_VARIATION(27, L"Autoincrementable column - DBPROP_COL_AUTOINCREMENT")
|
|
TEST_VARIATION(28, L"DBPROP_COL_DEFAULT")
|
|
TEST_VARIATION(29, L"DBPROP_COL_DESCRIPTION")
|
|
TEST_VARIATION(30, L"DBPROP_COL_FIXEDLENGTH")
|
|
TEST_VARIATION(31, L"DBPROP_COL_NULLABLE")
|
|
TEST_VARIATION(32, L"DBPROP_PRIMARYKEY")
|
|
TEST_VARIATION(33, L"DBPROP_COL_UNIQUE")
|
|
TEST_VARIATION(34, L"Duplicate an existing column => DB_E_DUPLCATECOLUMNID")
|
|
TEST_VARIATION(35, L"Abort retaining")
|
|
TEST_VARIATION(36, L"Abort without retaining")
|
|
TEST_VARIATION(37, L"Commit with retain")
|
|
TEST_VARIATION(38, L"Commit without retain")
|
|
TEST_VARIATION(39, L"Add a column for each provider type in an empty table => S_OK")
|
|
TEST_VARIATION(40, L"Add a column to a table created with a SQL command => S_OK")
|
|
TEST_VARIATION(41, L"Drop all the column of a table (via SQL stmt) and then try to add a column => S_OK")
|
|
TEST_VARIATION(42, L"Non NULL pTypeInfo in DBCOLUMNDESC => DB_E_BADTYPE")
|
|
TEST_VARIATION(43, L"Missmatch between wType and pwszTypeName => DB_E_BADTYPE")
|
|
TEST_VARIATION(44, L"Add a not nullable column and try to insert a null value for it")
|
|
TEST_VARIATION(45, L"Add a column on a view")
|
|
TEST_VARIATION(46, L"eKind != DBKIND_NAME for a column")
|
|
TEST_VARIATION(47, L"threads with different column")
|
|
TEST_VARIATION(48, L"threads on the same column")
|
|
TEST_VARIATION(49, L"add columns of alll known wType => S_OK")
|
|
TEST_VARIATION(50, L"Fully Qualified table name")
|
|
TEST_VARIATION(51, L"Quoted Table Name")
|
|
TEST_VARIATION(52, L"pColumnDesc == NULL => E_INVALIDARG")
|
|
TEST_VARIATION(53, L"cPropertySets != 0 and rgPropertySets == NULL in pColumnDesc => E_INVALIDARG")
|
|
TEST_VARIATION(54, L"cPropertySets == 0 and rgPropertySets != NULL in pColumnDesc => S_OK")
|
|
TEST_VARIATION(55, L"cProperties == 0 and rgProperties != NULL in pColumnDesc's propset => S_OK")
|
|
TEST_VARIATION(56, L"cProperties != 0 and rgProperties == NULL in pColumnDesc's propset => E_INVALIDARG")
|
|
TEST_VARIATION(57, L"pclsid not null")
|
|
TEST_VARIATION(58, L"NULL pwszTypeName => S_OK")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCDropColumn)
|
|
//--------------------------------------------------------------------
|
|
// @class Test case for dropping columns
|
|
//
|
|
class TCDropColumn : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCDropColumn,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember pTableID is NULL => E_INVALIDARG
|
|
int Variation_1();
|
|
// @cmember pColumnID in NULL => E_INVALIDARG
|
|
int Variation_2();
|
|
// @cmember *pTableID is DB_NULLID => DB_E_NOTABLE
|
|
int Variation_3();
|
|
// @cmember *pColumnID is DB_NULLID => DB_E_NOCOLUMN
|
|
int Variation_4();
|
|
// @cmember Maximum length table name => S_OK
|
|
int Variation_5();
|
|
// @cmember 1-char-too long table name => DB_E_NOTABLE
|
|
int Variation_6();
|
|
// @cmember *pTableID contains a NULL table name => DB_E_NOTABLE
|
|
int Variation_7();
|
|
// @cmember *pTableID contains an invalid name => DB_E_NOTABLE
|
|
int Variation_8();
|
|
// @cmember Maximum length for a column name => S_OK
|
|
int Variation_9();
|
|
// @cmember 1-char-too-long column name => DB_E_NOCOLUMN
|
|
int Variation_10();
|
|
// @cmember *pColumnID contains a NULL column name pointer => E_INVALIDARG
|
|
int Variation_11();
|
|
// @cmember *pColumnID contains an invalid column name => E_INVALID ARG
|
|
int Variation_12();
|
|
// @cmember Drop all the columns of a table => S_OK
|
|
int Variation_13();
|
|
// @cmember Try to delete an inexistent column => DB_E_NOCOLUMN
|
|
int Variation_14();
|
|
// @cmember Table in use => DB_E_TABLEINUSE
|
|
int Variation_15();
|
|
// @cmember Valid name of an inexistent table => DB_E_NOTABLE
|
|
int Variation_16();
|
|
// @cmember Abort with retaining
|
|
int Variation_17();
|
|
// @cmember Abort without retaining
|
|
int Variation_18();
|
|
// @cmember Commit with retaining
|
|
int Variation_19();
|
|
// @cmember Commit without retaining
|
|
int Variation_20();
|
|
// @cmember threads on different columns
|
|
int Variation_21();
|
|
// @cmember threads on the same column
|
|
int Variation_22();
|
|
// @cmember Drop a column twice => DB_E_NOCOLUMN
|
|
int Variation_23();
|
|
// @cmember 2 TableDefinition interfaces on the same table, try to drop 2 different columns => S_OK
|
|
int Variation_24();
|
|
// @cmember Drop as many column as possible from a table created with a SQL statement
|
|
int Variation_25();
|
|
// @cmember Drop a column from a 2 column table
|
|
int Variation_26();
|
|
// @cmember drop a column from a 1 column table
|
|
int Variation_27();
|
|
// @cmember drop a column from a non empty table => S_OK
|
|
int Variation_28();
|
|
// @cmember drop a column from an empty table
|
|
int Variation_29();
|
|
// @cmember drop a nullable, an autoincrementable and a default value column
|
|
int Variation_30();
|
|
// @cmember try to drop a column from a view
|
|
int Variation_31();
|
|
// @cmember drop a column added with an alter table command => S_OK
|
|
int Variation_32();
|
|
// @cmember try to drop columns using different DBKIND pattern
|
|
int Variation_33();
|
|
// @cmember Fully Qualified Table Name
|
|
int Variation_34();
|
|
// @cmember Quoted Table Name
|
|
int Variation_35();
|
|
// }} TCW_TESTVARS_END
|
|
|
|
unsigned MyThreadProc(ULONG i);
|
|
};
|
|
// {{ TCW_TESTCASE(TCDropColumn)
|
|
#define THE_CLASS TCDropColumn
|
|
BEG_TEST_CASE(TCDropColumn, TCITableDefinition, L"Test case for dropping columns")
|
|
TEST_VARIATION(1, L"pTableID is NULL => E_INVALIDARG")
|
|
TEST_VARIATION(2, L"pColumnID in NULL => E_INVALIDARG")
|
|
TEST_VARIATION(3, L"*pTableID is DB_NULLID => DB_E_NOTABLE")
|
|
TEST_VARIATION(4, L"*pColumnID is DB_NULLID => DB_E_NOCOLUMN")
|
|
TEST_VARIATION(5, L"Maximum length table name => S_OK")
|
|
TEST_VARIATION(6, L"1-char-too long table name => DB_E_NOTABLE")
|
|
TEST_VARIATION(7, L"*pTableID contains a NULL table name => DB_E_NOTABLE")
|
|
TEST_VARIATION(8, L"*pTableID contains an invalid name => DB_E_NOTABLE")
|
|
TEST_VARIATION(9, L"Maximum length for a column name => S_OK")
|
|
TEST_VARIATION(10, L"1-char-too-long column name => DB_E_NOCOLUMN")
|
|
TEST_VARIATION(11, L"*pColumnID contains a NULL column name pointer => E_INVALIDARG")
|
|
TEST_VARIATION(12, L"*pColumnID contains an invalid column name => E_INVALID ARG")
|
|
TEST_VARIATION(13, L"Drop all the columns of a table => S_OK")
|
|
TEST_VARIATION(14, L"Try to delete an inexistent column => DB_E_NOCOLUMN")
|
|
TEST_VARIATION(15, L"Table in use => DB_E_TABLEINUSE")
|
|
TEST_VARIATION(16, L"Valid name of an inexistent table => DB_E_NOTABLE")
|
|
TEST_VARIATION(17, L"Abort with retaining")
|
|
TEST_VARIATION(18, L"Abort without retaining")
|
|
TEST_VARIATION(19, L"Commit with retaining")
|
|
TEST_VARIATION(20, L"Commit without retaining")
|
|
TEST_VARIATION(21, L"threads on different columns")
|
|
TEST_VARIATION(22, L"threads on the same column")
|
|
TEST_VARIATION(23, L"Drop a column twice => DB_E_NOCOLUMN")
|
|
TEST_VARIATION(24, L"2 TableDefinition interfaces on the same table, try to drop 2 different columns => S_OK")
|
|
TEST_VARIATION(25, L"Drop as many column as possible from a table created with a SQL statement")
|
|
TEST_VARIATION(26, L"Drop a column from a 2 column table")
|
|
TEST_VARIATION(27, L"drop a column from a 1 column table")
|
|
TEST_VARIATION(28, L"drop a column from a non empty table => S_OK")
|
|
TEST_VARIATION(29, L"drop a column from an empty table")
|
|
TEST_VARIATION(30, L"drop a nullable, an autoincrementable and a default value column")
|
|
TEST_VARIATION(31, L"try to drop a column from a view")
|
|
TEST_VARIATION(32, L"drop a column added with an alter table command => S_OK")
|
|
TEST_VARIATION(33, L"try to drop columns using different DBKIND pattern")
|
|
TEST_VARIATION(34, L"Fully Qualified Table Name")
|
|
TEST_VARIATION(35, L"Quoted Table Name")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCDropTable)
|
|
//--------------------------------------------------------------------
|
|
// @class Test Case fo dropping a table
|
|
//
|
|
class TCDropTable : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCDropTable,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember pTableID is NULL => E_INVALIDARG
|
|
int Variation_1();
|
|
// @cmember *pTableID is DB_NULLID => DB_E_NOTABLE
|
|
int Variation_2();
|
|
// @cmember Maximum length for table name => S_OK
|
|
int Variation_3();
|
|
// @cmember 1-char-too-long table name => DB_E_NOTABLE
|
|
int Variation_4();
|
|
// @cmember The pointer to the table name is NULL => DB_E_NOTABLE
|
|
int Variation_5();
|
|
// @cmember Table name is empty => DB_E_NOTABLE
|
|
int Variation_6();
|
|
// @cmember Invalid table name => DB_E_NOTABLE
|
|
int Variation_7();
|
|
// @cmember A rowset is opened on table => DB_E_TABLEINUSE
|
|
int Variation_8();
|
|
// @cmember Table in use => DB_E_TABLEINUSE
|
|
int Variation_9();
|
|
// @cmember Inexistent table => DB_E_NOTABLE
|
|
int Variation_10();
|
|
// @cmember Abort with retaining
|
|
int Variation_11();
|
|
// @cmember Abort without retaining
|
|
int Variation_12();
|
|
// @cmember Commit with retaining
|
|
int Variation_13();
|
|
// @cmember Commit without retaining
|
|
int Variation_14();
|
|
// @cmember Drop a table created with an SQL command => S_OK
|
|
int Variation_15();
|
|
// @cmember Drop a table created with ITableDefinition, no rowset created => S_OK
|
|
int Variation_16();
|
|
// @cmember Drop a table created with ITableDefinition, rowset released => S_OK
|
|
int Variation_17();
|
|
// @cmember ITableDefinition::CreateTable, insert 10 rows, release rowset, drop the table => S_OK
|
|
int Variation_18();
|
|
// @cmember For each provider type, create a table with a single column and then drop it => S_OK
|
|
int Variation_19();
|
|
// @cmember Drop a table twice => DB_E_NOTABLE
|
|
int Variation_20();
|
|
// @cmember threads on different tables
|
|
int Variation_21();
|
|
// @cmember threads on same table
|
|
int Variation_22();
|
|
// @cmember Fully Qualified Table Name
|
|
int Variation_23();
|
|
// @cmember Quoted Table Name
|
|
int Variation_24();
|
|
// @cmember Different DBKINDs for pTableID
|
|
int Variation_25();
|
|
// }} TCW_TESTVARS_END
|
|
|
|
unsigned MyThreadProc(ULONG i);
|
|
};
|
|
// {{ TCW_TESTCASE(TCDropTable)
|
|
#define THE_CLASS TCDropTable
|
|
BEG_TEST_CASE(TCDropTable, TCITableDefinition, L"Test Case fo dropping a table")
|
|
TEST_VARIATION(1, L"pTableID is NULL => E_INVALIDARG")
|
|
TEST_VARIATION(2, L"*pTableID is DB_NULLID => DB_E_NOTABLE")
|
|
TEST_VARIATION(3, L"Maximum length for table name => S_OK")
|
|
TEST_VARIATION(4, L"1-char-too-long table name => DB_E_NOTABLE")
|
|
TEST_VARIATION(5, L"The pointer to the table name is NULL => DB_E_NOTABLE")
|
|
TEST_VARIATION(6, L"Table name is empty => DB_E_NOTABLE")
|
|
TEST_VARIATION(7, L"Invalid table name => DB_E_NOTABLE")
|
|
TEST_VARIATION(8, L"A rowset is opened on table => DB_E_TABLEINUSE")
|
|
TEST_VARIATION(9, L"Table in use => DB_E_TABLEINUSE")
|
|
TEST_VARIATION(10, L"Inexistent table => DB_E_NOTABLE")
|
|
TEST_VARIATION(11, L"Abort with retaining")
|
|
TEST_VARIATION(12, L"Abort without retaining")
|
|
TEST_VARIATION(13, L"Commit with retaining")
|
|
TEST_VARIATION(14, L"Commit without retaining")
|
|
TEST_VARIATION(15, L"Drop a table created with an SQL command => S_OK")
|
|
TEST_VARIATION(16, L"Drop a table created with ITableDefinition, no rowset created => S_OK")
|
|
TEST_VARIATION(17, L"Drop a table created with ITableDefinition, rowset released => S_OK")
|
|
TEST_VARIATION(18, L"ITableDefinition::CreateTable, insert 10 rows, release rowset, drop the table => S_OK")
|
|
TEST_VARIATION(19, L"For each provider type, create a table with a single column and then drop it => S_OK")
|
|
TEST_VARIATION(20, L"Drop a table twice => DB_E_NOTABLE")
|
|
TEST_VARIATION(21, L"threads on different tables")
|
|
TEST_VARIATION(22, L"threads on same table")
|
|
TEST_VARIATION(23, L"Fully Qualified Table Name")
|
|
TEST_VARIATION(24, L"Quoted Table Name")
|
|
TEST_VARIATION(25, L"Different DBKINDs for pTableID")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCCreateTable)
|
|
//--------------------------------------------------------------------
|
|
// @class TestCase for table creation
|
|
//
|
|
class TCCreateTable : public TCITableDefinition {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCCreateTable,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Session interfaces
|
|
int Variation_1();
|
|
// @cmember pTableID is NULL => S_OK
|
|
int Variation_2();
|
|
// @cmember ppTableID is a NULL pointer => S_OK
|
|
int Variation_3();
|
|
// @cmember pTableID and ppTableID both NULL => E_INVALIDARG
|
|
int Variation_4();
|
|
// @cmember *pTableID == DB_NULLID => DB_E_BADTABLEID
|
|
int Variation_5();
|
|
// @cmember cColumnDesc == 0 => E_INVALIDARG or S_OK
|
|
int Variation_6();
|
|
// @cmember rgColumnDesc == NULL => E_INVALIDARG
|
|
int Variation_7();
|
|
// @cmember cPropertySets != 0 and rgPropertySets == NULL => E_INVALIDARG
|
|
int Variation_8();
|
|
// @cmember cPropertySets is 0 and rgPropertySets != NULL => S_OK
|
|
int Variation_9();
|
|
// @cmember for a property sets, cProperties != 0 and rgProperties == NULL => E_INVALIDARG
|
|
int Variation_10();
|
|
// @cmember cProperties == 0 on a property set => S_OK
|
|
int Variation_11();
|
|
// @cmember for a column, rgPropertySets is NULL though cPropertySets != 0 => E_INVALIDARG
|
|
int Variation_12();
|
|
// @cmember dbcid in an element of rgColumnDesc is DB_NULLID => DB_E_BADCOLUMNID
|
|
int Variation_13();
|
|
// @cmember dbcid in an element of rgColumnDesc is NULL => DB_E_BADCOLUMNID
|
|
int Variation_14();
|
|
// @cmember not null pclsid in a DBCOLUMNDESC element
|
|
int Variation_15();
|
|
// @cmember empty column name => DB_E_BADCOLUMNID
|
|
int Variation_16();
|
|
// @cmember empty table name => DB_E_BADTABLEID
|
|
int Variation_17();
|
|
// @cmember Maximum length for table name => S_OK
|
|
int Variation_18();
|
|
// @cmember 1 char too long table name => DB_E_BADTABLEID
|
|
int Variation_19();
|
|
// @cmember Maximum length column name => S_OK
|
|
int Variation_20();
|
|
// @cmember 1 char too long column name => DB_E_BADCOLUMNID
|
|
int Variation_21();
|
|
// @cmember ulColumnSize 0 for a variable-length column => S_OK
|
|
int Variation_22();
|
|
// @cmember For each provider type create and drop a table with a single column => S_OK
|
|
int Variation_23();
|
|
// @cmember invalid table name => DB_E_BADTABLEID
|
|
int Variation_24();
|
|
// @cmember pTableID provides the name of an existing table => DB_E_DUPLICATETABLEID
|
|
int Variation_25();
|
|
// @cmember valid riid and NULL ppRowset => S_OK
|
|
int Variation_26();
|
|
// @cmember invalid column name => DB_E_BADCOLUMNID
|
|
int Variation_27();
|
|
// @cmember invalid type name for a column (NULL, empty or inexistent)
|
|
int Variation_28();
|
|
// @cmember invalid wType for a column => DB_E_BADTYPE
|
|
int Variation_29();
|
|
// @cmember wType and pswzTypeName mismatch in a column description => DB_E_BADTYPE
|
|
int Variation_30();
|
|
// @cmember not null pTypeInfo => DB_E_BADTYPE (for the time being
|
|
int Variation_31();
|
|
// @cmember duplicate column identifiers => DB_E_DUPLICATECOLUMNID
|
|
int Variation_32();
|
|
// @cmember improper eKind value in a DBID => DB_E_BADCOLUMNID
|
|
int Variation_33();
|
|
// @cmember invalid property value on column
|
|
int Variation_34();
|
|
// @cmember Invalid column precision => DB_E_BADPRECISION
|
|
int Variation_35();
|
|
// @cmember invalid scale on column => DB_E_BADSCALE
|
|
int Variation_36();
|
|
// @cmember col prop is not in the Column, Rowset or Table property group and dwOption is DBPROP_SETIFCHEAP => DB_S_ERRORSOCCURRED
|
|
int Variation_37();
|
|
// @cmember col prop is not in the Column, Rowset or Table property group and dwOption is DBPROP_REQUIRED => DB_E_ERRORSOCCURRED
|
|
int Variation_38();
|
|
// @cmember invalid propID for a column propriety
|
|
int Variation_39();
|
|
// @cmember colid in DBPROP of a column property is ignored
|
|
int Variation_40();
|
|
// @cmember Abort retaining
|
|
int Variation_41();
|
|
// @cmember Abort without retaining
|
|
int Variation_42();
|
|
// @cmember Commit retain
|
|
int Variation_43();
|
|
// @cmember Commit non-retaining
|
|
int Variation_44();
|
|
// @cmember Autoincrementable columns
|
|
int Variation_45();
|
|
// @cmember Default values
|
|
int Variation_46();
|
|
// @cmember Column descriptions
|
|
int Variation_47();
|
|
// @cmember Variable length columns
|
|
int Variation_48();
|
|
// @cmember Nullable/non nullable columns
|
|
int Variation_49();
|
|
// @cmember Primary key column
|
|
int Variation_50();
|
|
// @cmember Unique columns
|
|
int Variation_51();
|
|
// @cmember Test conflicting properties
|
|
int Variation_52();
|
|
// @cmember Create a table and ask for a rowset, setting DBPROP_ABORTPRESERVE
|
|
int Variation_53();
|
|
// @cmember Inserting rows after table creation, using the resulting rowset
|
|
int Variation_54();
|
|
// @cmember Delete rows in the created rowset
|
|
int Variation_55();
|
|
// @cmember Aggregation, ask for IID_IUnknown
|
|
int Variation_56();
|
|
// @cmember Create a table and ask for a rowset, setting DBPROP_COMMITPRESERVE
|
|
int Variation_57();
|
|
// @cmember Create a table and ask for a rowset, setting DBPROP_OWNINSERT
|
|
int Variation_58();
|
|
// @cmember Create a table and ask for a rowset, setting DBPROP_BOOKMARKS
|
|
int Variation_59();
|
|
// @cmember Create a table and ask for a rowset, setting DBPROP_CANHOLDROWS
|
|
int Variation_60();
|
|
// @cmember Create a table and ask for a rowset, setting DBPROP_MAYWRITECOLUMN
|
|
int Variation_61();
|
|
// @cmember Ask for a rowset mandatory/optional interface when table creation => S_OK
|
|
int Variation_62();
|
|
// @cmember threads on different tables
|
|
int Variation_63();
|
|
// @cmember threads on the same table
|
|
int Variation_64();
|
|
// @cmember try all interfaces on rowset that can be returned
|
|
int Variation_65();
|
|
// @cmember create with a table property => S_OK
|
|
int Variation_66();
|
|
// @cmember create a table and update a row, using the rowset interface got => S_OK
|
|
int Variation_67();
|
|
// @cmember Fully Qualified Table Name
|
|
int Variation_68();
|
|
// @cmember Quoted table name
|
|
int Variation_69();
|
|
// @cmember Aggregation, non IID_IUnknown
|
|
int Variation_70();
|
|
// @cmember Aggregation -> IRowsetInfo::GetReferencedRowset
|
|
int Variation_71();
|
|
// @cmember Agg session -> IRowsetInfo::GetSpecification
|
|
int Variation_72();
|
|
// @cmember Table -> Agg ColumnRowset, ask for non IID_IUnknown
|
|
int Variation_73();
|
|
// @cmember Table -> Agg ColumnRowset, ask for IID_IUnknown
|
|
int Variation_74();
|
|
// @cmember Table -> Agg ColumnRowset -> IRowsetInfo::GetSpecification
|
|
int Variation_75();
|
|
// @cmember colid is ignored in a non column specific rowset property
|
|
int Variation_76();
|
|
// @cmember colid is DB_NULLID in a column specific rowset property => S_OK
|
|
int Variation_77();
|
|
// @cmember valid, non DB_NULLID colid for a column specific rowset property
|
|
int Variation_78();
|
|
// @cmember invalid colid for a column specific rowset property
|
|
int Variation_79();
|
|
// @cmember Create a table. Retrieve a rowset on it (IRowsetInfo). Check GetSpecification()
|
|
int Variation_80();
|
|
// @cmember DB_NULLID is ignored for non column-related table properties
|
|
int Variation_81();
|
|
// @cmember Column related table property set to bad colid
|
|
int Variation_82();
|
|
// @cmember How many DBTYPE_I4 columns?
|
|
int Variation_83();
|
|
// @cmember Open a rowset with CE, call IColumnRowset with an aggregated pIUnk
|
|
int Variation_84();
|
|
// @cmember Different DBKINDs for pTableID
|
|
int Variation_85();
|
|
// @cmember Different DBKINDs for column IDs
|
|
int Variation_86();
|
|
// }} TCW_TESTVARS_END
|
|
|
|
unsigned MyThreadProc(ULONG i);
|
|
};
|
|
// {{ TCW_TESTCASE(TCCreateTable)
|
|
#define THE_CLASS TCCreateTable
|
|
BEG_TEST_CASE(TCCreateTable, TCITableDefinition, L"TestCase for table creation")
|
|
TEST_VARIATION(1, L"Session interfaces")
|
|
TEST_VARIATION(2, L"pTableID is NULL => S_OK")
|
|
TEST_VARIATION(3, L"ppTableID is a NULL pointer => S_OK")
|
|
TEST_VARIATION(4, L"pTableID and ppTableID both NULL => E_INVALIDARG")
|
|
TEST_VARIATION(5, L"*pTableID == DB_NULLID => DB_E_BADTABLEID")
|
|
TEST_VARIATION(6, L"cColumnDesc == 0 => E_INVALIDARG or S_OK")
|
|
TEST_VARIATION(7, L"rgColumnDesc == NULL => E_INVALIDARG")
|
|
TEST_VARIATION(8, L"cPropertySets != 0 and rgPropertySets == NULL => E_INVALIDARG")
|
|
TEST_VARIATION(9, L"cPropertySets is 0 and rgPropertySets != NULL => S_OK")
|
|
TEST_VARIATION(10, L"for a property sets, cProperties != 0 and rgProperties == NULL => E_INVALIDARG")
|
|
TEST_VARIATION(11, L"cProperties == 0 on a property set => S_OK")
|
|
TEST_VARIATION(12, L"for a column, rgPropertySets is NULL though cPropertySets != 0 => E_INVALIDARG")
|
|
TEST_VARIATION(13, L"dbcid in an element of rgColumnDesc is DB_NULLID => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(14, L"dbcid in an element of rgColumnDesc is NULL => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(15, L"not null pclsid in a DBCOLUMNDESC element")
|
|
TEST_VARIATION(16, L"empty column name => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(17, L"empty table name => DB_E_BADTABLEID")
|
|
TEST_VARIATION(18, L"Maximum length for table name => S_OK")
|
|
TEST_VARIATION(19, L"1 char too long table name => DB_E_BADTABLEID")
|
|
TEST_VARIATION(20, L"Maximum length column name => S_OK")
|
|
TEST_VARIATION(21, L"1 char too long column name => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(22, L"ulColumnSize 0 for a variable-length column => S_OK")
|
|
TEST_VARIATION(23, L"For each provider type create and drop a table with a single column => S_OK")
|
|
TEST_VARIATION(24, L"invalid table name => DB_E_BADTABLEID")
|
|
TEST_VARIATION(25, L"pTableID provides the name of an existing table => DB_E_DUPLICATETABLEID")
|
|
TEST_VARIATION(26, L"valid riid and NULL ppRowset => S_OK")
|
|
TEST_VARIATION(27, L"invalid column name => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(28, L"invalid type name for a column (NULL, empty or inexistent)")
|
|
TEST_VARIATION(29, L"invalid wType for a column => DB_E_BADTYPE")
|
|
TEST_VARIATION(30, L"wType and pswzTypeName mismatch in a column description => DB_E_BADTYPE")
|
|
TEST_VARIATION(31, L"not null pTypeInfo => DB_E_BADTYPE (for the time being")
|
|
TEST_VARIATION(32, L"duplicate column identifiers => DB_E_DUPLICATECOLUMNID")
|
|
TEST_VARIATION(33, L"improper eKind value in a DBID => DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(34, L"invalid property value on column")
|
|
TEST_VARIATION(35, L"Invalid column precision => DB_E_BADPRECISION")
|
|
TEST_VARIATION(36, L"invalid scale on column => DB_E_BADSCALE")
|
|
TEST_VARIATION(37, L"col prop is not in the Column, Rowset or Table property group and dwOption is DBPROP_SETIFCHEAP => DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(38, L"col prop is not in the Column, Rowset or Table property group and dwOption is DBPROP_REQUIRED => DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(39, L"invalid propID for a column propriety")
|
|
TEST_VARIATION(40, L"colid in DBPROP of a column property is ignored")
|
|
TEST_VARIATION(41, L"Abort retaining")
|
|
TEST_VARIATION(42, L"Abort without retaining")
|
|
TEST_VARIATION(43, L"Commit retain")
|
|
TEST_VARIATION(44, L"Commit non-retaining")
|
|
TEST_VARIATION(45, L"Autoincrementable columns")
|
|
TEST_VARIATION(46, L"Default values")
|
|
TEST_VARIATION(47, L"Column descriptions")
|
|
TEST_VARIATION(48, L"Variable length columns")
|
|
TEST_VARIATION(49, L"Nullable/non nullable columns")
|
|
TEST_VARIATION(50, L"Primary key column")
|
|
TEST_VARIATION(51, L"Unique columns")
|
|
TEST_VARIATION(52, L"Test conflicting properties")
|
|
TEST_VARIATION(53, L"Create a table and ask for a rowset, setting DBPROP_ABORTPRESERVE")
|
|
TEST_VARIATION(54, L"Inserting rows after table creation, using the resulting rowset")
|
|
TEST_VARIATION(55, L"Delete rows in the created rowset")
|
|
TEST_VARIATION(56, L"Aggregation, ask for IID_IUnknown")
|
|
TEST_VARIATION(57, L"Create a table and ask for a rowset, setting DBPROP_COMMITPRESERVE")
|
|
TEST_VARIATION(58, L"Create a table and ask for a rowset, setting DBPROP_OWNINSERT")
|
|
TEST_VARIATION(59, L"Create a table and ask for a rowset, setting DBPROP_BOOKMARKS")
|
|
TEST_VARIATION(60, L"Create a table and ask for a rowset, setting DBPROP_CANHOLDROWS")
|
|
TEST_VARIATION(61, L"Create a table and ask for a rowset, setting DBPROP_MAYWRITECOLUMN")
|
|
TEST_VARIATION(62, L"Ask for a rowset mandatory/optional interface when table creation => S_OK")
|
|
TEST_VARIATION(63, L"threads on different tables")
|
|
TEST_VARIATION(64, L"threads on the same table")
|
|
TEST_VARIATION(65, L"try all interfaces on rowset that can be returned")
|
|
TEST_VARIATION(66, L"create with a table property => S_OK")
|
|
TEST_VARIATION(67, L"create a table and update a row, using the rowset interface got => S_OK")
|
|
TEST_VARIATION(68, L"Fully Qualified Table Name")
|
|
TEST_VARIATION(69, L"Quoted table name")
|
|
TEST_VARIATION(70, L"Aggregation, non IID_IUnknown")
|
|
TEST_VARIATION(71, L"Aggregation -> IRowsetInfo::GetReferencedRowset")
|
|
TEST_VARIATION(72, L"Agg session -> IRowsetInfo::GetSpecification")
|
|
TEST_VARIATION(73, L"Table -> Agg ColumnRowset, ask for non IID_IUnknown")
|
|
TEST_VARIATION(74, L"Table -> Agg ColumnRowset, ask for IID_IUnknown")
|
|
TEST_VARIATION(75, L"Table -> Agg ColumnRowset -> IRowsetInfo::GetSpecification")
|
|
TEST_VARIATION(76, L"colid is ignored in a non column specific rowset property")
|
|
TEST_VARIATION(77, L"colid is DB_NULLID in a column specific rowset property => S_OK")
|
|
TEST_VARIATION(78, L"valid, non DB_NULLID colid for a column specific rowset property")
|
|
TEST_VARIATION(79, L"invalid colid for a column specific rowset property")
|
|
TEST_VARIATION(80, L"Create a table. Retrieve a rowset on it (IRowsetInfo). Check GetSpecification()")
|
|
TEST_VARIATION(81, L"DB_NULLID is ignored for non column-related table properties")
|
|
TEST_VARIATION(82, L"Column related table property set to bad colid")
|
|
TEST_VARIATION(83, L"How many DBTYPE_I4 columns?")
|
|
TEST_VARIATION(84, L"Open a rowset with CE, call IColumnRowset with an aggregated pIUnk")
|
|
TEST_VARIATION(85, L"Different DBKINDs for pTableID")
|
|
TEST_VARIATION(86, L"Different DBKINDs for column IDs")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(RODataSource)
|
|
//--------------------------------------------------------------------
|
|
// @class Test case for operating on a read only data source
|
|
//
|
|
class RODataSource : public TCDropColumn {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
IUnknown *m_pIUnknown;
|
|
IUnknown *m_pIUnknown2;
|
|
ITableDefinition *m_pITableDefinition2;
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(RODataSource,TCDropColumn);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Add a column
|
|
int Variation_1();
|
|
// @cmember Drop a column
|
|
int Variation_2();
|
|
// @cmember Create a table
|
|
int Variation_3();
|
|
// @cmember Drop a table
|
|
int Variation_4();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
|
|
// {{ TCW_TESTCASE(RODataSource)
|
|
#define THE_CLASS RODataSource
|
|
BEG_TEST_CASE(RODataSource, TCDropColumn, L"Test case for operating on a read only data source")
|
|
TEST_VARIATION(1, L"Add a column")
|
|
TEST_VARIATION(2, L"Drop a column")
|
|
TEST_VARIATION(3, L"Create a table")
|
|
TEST_VARIATION(4, L"Drop a table")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAddConstraint_Boundary)
|
|
//*-----------------------------------------------------------------------
|
|
// @class General and boundary/null test for ITableDefinitionWithConstraints::AddConstraint
|
|
//
|
|
class TCAddConstraint_Boundary : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAddConstraint_Boundary,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Check the session object (QI for interfaces)
|
|
int Variation_1();
|
|
// @cmember pTableID is NULL => E_INVALIDARG
|
|
int Variation_2();
|
|
// @cmember *pTableID is DB_NULLID => DB_E_NOTABLE
|
|
int Variation_3();
|
|
// @cmember Table name is NULL => DB_E_NOTABLE
|
|
int Variation_4();
|
|
// @cmember Table name is the empty string => DB_E_NOTABLE
|
|
int Variation_5();
|
|
// @cmember Table name has maximum length
|
|
int Variation_6();
|
|
// @cmember Table name exceeds maximum length => DB_E_NOTABLE
|
|
int Variation_7();
|
|
// @cmember Table name contains illegal characters
|
|
int Variation_8();
|
|
// @cmember Invalid DBKIND value for the base table
|
|
int Variation_9();
|
|
// @cmember NULL column list in a constraint, column size is not 0 => E_INVALIDARG
|
|
int Variation_10();
|
|
// @cmember NULL column name in a constraint
|
|
int Variation_11();
|
|
// @cmember Empty string for a column name
|
|
int Variation_12();
|
|
// @cmember Maximum length column name in a constraint
|
|
int Variation_13();
|
|
// @cmember Column name exceeds maximum length
|
|
int Variation_14();
|
|
// @cmember Invalid DBKIND for a column DBID of a constraint
|
|
int Variation_15();
|
|
// @cmember Column ID is DB_NULLID
|
|
int Variation_16();
|
|
// @cmember NULL pReferencedTableID for a foreign key constraint (with and without cForeignKeyColumns being 0)
|
|
int Variation_17();
|
|
// @cmember DBNULL_ID *pReferencedTableID for a foreign key constraint
|
|
int Variation_18();
|
|
// @cmember NULL referenced table name for a foreign key constraint
|
|
int Variation_19();
|
|
// @cmember Emptry string referenced table name for a foreign key constraint
|
|
int Variation_20();
|
|
// @cmember Maximum length referenced table name for a foreign key constraint
|
|
int Variation_21();
|
|
// @cmember Referenced table name longer than allowed for a foreign key constraint
|
|
int Variation_22();
|
|
// @cmember Illegal characters in the referenced table name for a foreign key constraint
|
|
int Variation_23();
|
|
// @cmember Bad constraint type
|
|
int Variation_24();
|
|
// @cmember Empty list of columns for a unique, primay key or foreign key constraint
|
|
int Variation_25();
|
|
// @cmember Non empty list of columns for a check constraint
|
|
int Variation_26();
|
|
// @cmember Not null pwszConstraintText in a unique, PK or FK constraint
|
|
int Variation_27();
|
|
// @cmember NULL pConstraintDesc => E_INVALIDARG
|
|
int Variation_28();
|
|
// @cmember 0 < cColumns and NULL == rgColumnList => E_INVALIDARG
|
|
int Variation_29();
|
|
// @cmember 0 < cForeignKeyColumns and NULL == rgForeignKeyColumnList => E_INVALIDARG
|
|
int Variation_30();
|
|
// @cmember Constraint is not foreign key and pReferencedTableID is not NULL
|
|
int Variation_31();
|
|
// @cmember Non empty list of foreign keys for a constraint that is not foreign key
|
|
int Variation_32();
|
|
// @cmember Inexistent referenced table
|
|
int Variation_33();
|
|
// @cmember Add several constraints to the table
|
|
int Variation_34();
|
|
// @cmember Inexistent table name => DB_E_NOTABLE
|
|
int Variation_35();
|
|
// @cmember Inexistent column name => DB_E_NOCOLUMN
|
|
int Variation_36();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAddConstraint_Boundary)
|
|
#define THE_CLASS TCAddConstraint_Boundary
|
|
BEG_TEST_CASE(TCAddConstraint_Boundary, TCITableDefinition, L"General and boundary/null test for ITableDefinitionWithConstraints::AddConstraint")
|
|
TEST_VARIATION(1, L"Check the session object (QI for interfaces)")
|
|
TEST_VARIATION(2, L"pTableID is NULL => E_INVALIDARG")
|
|
TEST_VARIATION(3, L"*pTableID is DB_NULLID => DB_E_NOTABLE")
|
|
TEST_VARIATION(4, L"Table name is NULL => DB_E_NOTABLE")
|
|
TEST_VARIATION(5, L"Table name is the empty string => DB_E_NOTABLE")
|
|
TEST_VARIATION(6, L"Table name has maximum length")
|
|
TEST_VARIATION(7, L"Table name exceeds maximum length => DB_E_NOTABLE")
|
|
TEST_VARIATION(8, L"Table name contains illegal characters")
|
|
TEST_VARIATION(9, L"Invalid DBKIND value for the base table")
|
|
TEST_VARIATION(10, L"NULL column list in a constraint, column size is not 0 => E_INVALIDARG")
|
|
TEST_VARIATION(11, L"NULL column name in a constraint")
|
|
TEST_VARIATION(12, L"Empty string for a column name")
|
|
TEST_VARIATION(13, L"Maximum length column name in a constraint")
|
|
TEST_VARIATION(14, L"Column name exceeds maximum length")
|
|
TEST_VARIATION(15, L"Invalid DBKIND for a column DBID of a constraint")
|
|
TEST_VARIATION(16, L"Column ID is DB_NULLID")
|
|
TEST_VARIATION(17, L"NULL pReferencedTableID for a foreign key constraint (with and without cForeignKeyColumns being 0)")
|
|
TEST_VARIATION(18, L"DBNULL_ID *pReferencedTableID for a foreign key constraint")
|
|
TEST_VARIATION(19, L"NULL referenced table name for a foreign key constraint")
|
|
TEST_VARIATION(20, L"Emptry string referenced table name for a foreign key constraint")
|
|
TEST_VARIATION(21, L"Maximum length referenced table name for a foreign key constraint")
|
|
TEST_VARIATION(22, L"Referenced table name longer than allowed for a foreign key constraint")
|
|
TEST_VARIATION(23, L"Illegal characters in the referenced table name for a foreign key constraint")
|
|
TEST_VARIATION(24, L"Bad constraint type")
|
|
TEST_VARIATION(25, L"Empty list of columns for a unique, primay key or foreign key constraint")
|
|
TEST_VARIATION(26, L"Non empty list of columns for a check constraint")
|
|
TEST_VARIATION(27, L"Not null pwszConstraintText in a unique, PK or FK constraint")
|
|
TEST_VARIATION(28, L"NULL pConstraintDesc => E_INVALIDARG")
|
|
TEST_VARIATION(29, L"0 < cColumns and NULL == rgColumnList => E_INVALIDARG")
|
|
TEST_VARIATION(30, L"0 < cForeignKeyColumns and NULL == rgForeignKeyColumnList => E_INVALIDARG")
|
|
TEST_VARIATION(31, L"Constraint is not foreign key and pReferencedTableID is not NULL")
|
|
TEST_VARIATION(32, L"Non empty list of foreign keys for a constraint that is not foreign key")
|
|
TEST_VARIATION(33, L"Inexistent referenced table")
|
|
TEST_VARIATION(34, L"Add several constraints to the table")
|
|
TEST_VARIATION(35, L"Inexistent table name => DB_E_NOTABLE")
|
|
TEST_VARIATION(36, L"Inexistent column name => DB_E_NOCOLUMN")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAddConstraint_UNIQUE)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_UNIQUE
|
|
//
|
|
class TCAddConstraint_UNIQUE : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAddConstraint_UNIQUE,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Create a table and try to apply the constraint on each column
|
|
int Variation_1();
|
|
// @cmember Set a unique constraint on each type of column
|
|
int Variation_2();
|
|
// @cmember Create a unique constraint that uses several columns
|
|
int Variation_3();
|
|
// @cmember Create several unique constraints on a table, no overlapping
|
|
int Variation_4();
|
|
// @cmember Create multiple, overlapping constraints on a table
|
|
int Variation_5();
|
|
// @cmember Create a constraint, drop it and recreate it
|
|
int Variation_6();
|
|
// @cmember Create a constraint on a null column
|
|
int Variation_7();
|
|
// @cmember Create a contraint on a not nullable column
|
|
int Variation_8();
|
|
// @cmember Create a constraint on a column that has a default value
|
|
int Variation_9();
|
|
// @cmember Create a constraint on a column defined as a primary key
|
|
int Variation_10();
|
|
// @cmember Create a constraint on a column defined as a foreign key
|
|
int Variation_11();
|
|
// @cmember Create a constraint on a column that is included in an index
|
|
int Variation_12();
|
|
// @cmember Use the name of an already existing constraint
|
|
int Variation_13();
|
|
// @cmember Constraint is created in a different catalog
|
|
int Variation_14();
|
|
// @cmember create a unique constraint on a non empty table
|
|
int Variation_15();
|
|
// @cmember Create a unique constraints on a column that has doubled values
|
|
int Variation_16();
|
|
// @cmember Abort retaining
|
|
int Variation_17();
|
|
// @cmember Abort non retaining
|
|
int Variation_18();
|
|
// @cmember Commit retaining
|
|
int Variation_19();
|
|
// @cmember Commit non retaining
|
|
int Variation_20();
|
|
// @cmember Maximum columns allowed in Unique constraint
|
|
int Variation_21();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAddConstraint_UNIQUE)
|
|
#define THE_CLASS TCAddConstraint_UNIQUE
|
|
BEG_TEST_CASE(TCAddConstraint_UNIQUE, TCITableDefinition, L"Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_UNIQUE")
|
|
TEST_VARIATION(1, L"Create a table and try to apply the constraint on each column")
|
|
TEST_VARIATION(2, L"Set a unique constraint on each type of column")
|
|
TEST_VARIATION(3, L"Create a unique constraint that uses several columns")
|
|
TEST_VARIATION(4, L"Create several unique constraints on a table, no overlapping")
|
|
TEST_VARIATION(5, L"Create multiple, overlapping constraints on a table")
|
|
TEST_VARIATION(6, L"Create a constraint, drop it and recreate it")
|
|
TEST_VARIATION(7, L"Create a constraint on a null column")
|
|
TEST_VARIATION(8, L"Create a contraint on a not nullable column")
|
|
TEST_VARIATION(9, L"Create a constraint on a column that has a default value")
|
|
TEST_VARIATION(10, L"Create a constraint on a column defined as a primary key")
|
|
TEST_VARIATION(11, L"Create a constraint on a column defined as a foreign key")
|
|
TEST_VARIATION(12, L"Create a constraint on a column that is included in an index")
|
|
TEST_VARIATION(13, L"Use the name of an already existing constraint")
|
|
TEST_VARIATION(14, L"Constraint is created in a different catalog")
|
|
TEST_VARIATION(15, L"create a unique constraint on a non empty table")
|
|
TEST_VARIATION(16, L"Create a unique constraints on a column that has doubled values")
|
|
TEST_VARIATION(17, L"Abort retaining")
|
|
TEST_VARIATION(18, L"Abort non retaining")
|
|
TEST_VARIATION(19, L"Commit retaining")
|
|
TEST_VARIATION(20, L"Commit non retaining")
|
|
TEST_VARIATION(21, L"Maximum columns allowed in unique constraint")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAddConstraint_PRIMARYKEY)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_PRIMARYKEY
|
|
//
|
|
class TCAddConstraint_PRIMARYKEY : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAddConstraint_PRIMARYKEY,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Create a table and try to apply the constraint on each column
|
|
int Variation_1();
|
|
// @cmember Set a primary key constraint on each type of column
|
|
int Variation_2();
|
|
// @cmember Create a primary key constraint. Drop it. Create a primary key using the same name as before.
|
|
int Variation_3();
|
|
// @cmember Create multiple-columned primary key
|
|
int Variation_4();
|
|
// @cmember Create multiple primary key constraints using successive calls
|
|
int Variation_5();
|
|
// @cmember Successive calls, lists of columns overlap
|
|
int Variation_6();
|
|
// @cmember Primary key constraint on a nullable column
|
|
int Variation_7();
|
|
// @cmember Primary key constraint on a not nullable column
|
|
int Variation_8();
|
|
// @cmember Primary key constraint on a column with a default value
|
|
int Variation_9();
|
|
// @cmember Primary key constraint on a column defined as unique
|
|
int Variation_10();
|
|
// @cmember Primary key constraint on a column defined as primary key => DB_E_DUPLICATECONSTRAINTID
|
|
int Variation_11();
|
|
// @cmember Primary key constraint on a column that already has a primary key constraint
|
|
int Variation_12();
|
|
// @cmember Primary key constraint on a column that is part of a foreign key constraint
|
|
int Variation_13();
|
|
// @cmember Primary key constraint on a column that is part of an index
|
|
int Variation_14();
|
|
// @cmember Primary key constraint on a column on a not empty table
|
|
int Variation_15();
|
|
// @cmember Primary key constraint on a column that already has duplicates (for the whole key)
|
|
int Variation_16();
|
|
// @cmember Primary key constraint that has duplicates for a column in the key, but not for the whole key
|
|
int Variation_17();
|
|
// @cmember Abort retaining
|
|
int Variation_18();
|
|
// @cmember Abort non retaining
|
|
int Variation_19();
|
|
// @cmember Commit retaining
|
|
int Variation_20();
|
|
// @cmember Commit non retaining
|
|
int Variation_21();
|
|
// @cmember Create PK in different catalog
|
|
int Variation_22();
|
|
// @cmember Find maximum limit on PKs
|
|
int Variation_23();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAddConstraint_PRIMARYKEY)
|
|
#define THE_CLASS TCAddConstraint_PRIMARYKEY
|
|
BEG_TEST_CASE(TCAddConstraint_PRIMARYKEY, TCITableDefinition, L"Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_PRIMARYKEY")
|
|
TEST_VARIATION(1, L"Create a table and try to apply the constraint on each column")
|
|
TEST_VARIATION(2, L"Set a primary key constraint on each type of column")
|
|
TEST_VARIATION(3, L"Create a primary key constraint. Drop it. Create a primary key using the same name as before.")
|
|
TEST_VARIATION(4, L"Create multiple-columned primary key")
|
|
TEST_VARIATION(5, L"Create multiple primary key constraints using successive calls")
|
|
TEST_VARIATION(6, L"Successive calls, lists of columns overlap")
|
|
TEST_VARIATION(7, L"Primary key constraint on a nullable column -> E_FAIL")
|
|
TEST_VARIATION(8, L"Primary key constraint on a not nullable column")
|
|
TEST_VARIATION(9, L"Primary key constraint on a column with a default value")
|
|
TEST_VARIATION(10, L"Primary key constraint on a column defined as unique")
|
|
TEST_VARIATION(11, L"Primary key constraint on a column defined as primary key => DB_E_DUPLICATECONSTRAINTID")
|
|
TEST_VARIATION(12, L"Primary key constraint on a column that already has a primary key constraint")
|
|
TEST_VARIATION(13, L"Primary key constraint on a column that is part of a foreign key constraint")
|
|
TEST_VARIATION(14, L"Primary key constraint on a column that is part of an index")
|
|
TEST_VARIATION(15, L"Primary key constraint on a column on a not empty table")
|
|
TEST_VARIATION(16, L"Primary key constraint on a column that already has duplicates (for the whole key)")
|
|
TEST_VARIATION(17, L"Primary key constraint that has duplicates for a column in the key, but not for the whole key")
|
|
TEST_VARIATION(18, L"Abort retaining")
|
|
TEST_VARIATION(19, L"Abort non retaining")
|
|
TEST_VARIATION(20, L"Commit retaining")
|
|
TEST_VARIATION(21, L"Commit non retaining")
|
|
TEST_VARIATION(22, L"Create primary key in a different catalog")
|
|
TEST_VARIATION(23, L"Find how many columns are supported in a PK")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAddConstraint_FOREIGNKEY)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_FOREIGNKEY
|
|
//
|
|
class TCAddConstraint_FOREIGNKEY : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
CTable *m_pReferenceTable;
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAddConstraint_FOREIGNKEY,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Simple foreign key constraint
|
|
int Variation_1();
|
|
// @cmember Foregin key is made of several columns
|
|
int Variation_2();
|
|
// @cmember Multiple foreign key constraints on a table
|
|
int Variation_3();
|
|
// @cmember Multiple overlapping foreign key constraints
|
|
int Variation_4();
|
|
// @cmember Create a foreign key on each column of the table
|
|
int Variation_5();
|
|
// @cmember Create a foreign key on all columns
|
|
int Variation_6();
|
|
// @cmember Create foreign key and try to drop the reference table
|
|
int Variation_7();
|
|
// @cmember On a nullable column
|
|
int Variation_8();
|
|
// @cmember On a not nullable column
|
|
int Variation_9();
|
|
// @cmember On a column having a default value
|
|
int Variation_10();
|
|
// @cmember On a column defined as unique
|
|
int Variation_11();
|
|
// @cmember On a primary key column
|
|
int Variation_12();
|
|
// @cmember On a column that is part of the index
|
|
int Variation_13();
|
|
// @cmember On a table that is in another catalog
|
|
int Variation_14();
|
|
// @cmember Use different combination for update/delete rules, as well as match type
|
|
int Variation_15();
|
|
// @cmember Referenced table name and base table names have maximum length
|
|
int Variation_16();
|
|
// @cmember Columns in the foreign key (base table and reference table) have different names
|
|
int Variation_17();
|
|
// @cmember Different size in column lists (base table and referenced)
|
|
int Variation_18();
|
|
// @cmember Column types in base table and reference table are different
|
|
int Variation_19();
|
|
// @cmember Invalid value for the update rule
|
|
int Variation_20();
|
|
// @cmember Invalid value for the delete rule
|
|
int Variation_21();
|
|
// @cmember Invalid value for the MatchType
|
|
int Variation_22();
|
|
// @cmember Inexistent column names in the referenced table
|
|
int Variation_23();
|
|
// @cmember Inexistent column name in the base table
|
|
int Variation_24();
|
|
// @cmember Inexistent base table
|
|
int Variation_25();
|
|
// @cmember Inexistent reference table
|
|
int Variation_26();
|
|
// @cmember NULL pConstraintID
|
|
int Variation_27();
|
|
// @cmember Referenced col list is not a unique / pk constraint => failure
|
|
int Variation_28();
|
|
// @cmember Create a foreign key and then insert a NULL value for one of the fk columns
|
|
int Variation_29();
|
|
// @cmember The referenced table and the base table are the same
|
|
int Variation_30();
|
|
// @cmember The base and referenced tables are temporary tables
|
|
int Variation_31();
|
|
// @cmember Base table is a temporary table
|
|
int Variation_32();
|
|
// @cmember Abort retaining
|
|
int Variation_33();
|
|
// @cmember Abort non retaining
|
|
int Variation_34();
|
|
// @cmember Commit retaining
|
|
int Variation_35();
|
|
// @cmember Commit non retaining
|
|
int Variation_36();
|
|
// @cmember The base table is already populated and the referenced one is empty => DB_E_SCHEMAVIOLATION
|
|
int Variation_37();
|
|
// @cmember Find maximum columns allowed in foreign keys
|
|
int Variation_38();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAddConstraint_FOREIGNKEY)
|
|
#define THE_CLASS TCAddConstraint_FOREIGNKEY
|
|
BEG_TEST_CASE(TCAddConstraint_FOREIGNKEY, TCITableDefinition, L"Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_FOREIGNKEY")
|
|
TEST_VARIATION(1, L"Simple foreign key constraint")
|
|
TEST_VARIATION(2, L"Foregin key is made of several columns")
|
|
TEST_VARIATION(3, L"Multiple foreign key constraints on a table")
|
|
TEST_VARIATION(4, L"Multiple overlapping foreign key constraints")
|
|
TEST_VARIATION(5, L"Create a foreign key on each column of the table")
|
|
TEST_VARIATION(6, L"Create a foreign key on all columns")
|
|
TEST_VARIATION(7, L"Create foreign key and try to drop the reference table")
|
|
TEST_VARIATION(8, L"On a nullable column")
|
|
TEST_VARIATION(9, L"On a not nullable column")
|
|
TEST_VARIATION(10, L"On a column having a default value")
|
|
TEST_VARIATION(11, L"On a column defined as unique")
|
|
TEST_VARIATION(12, L"On a primary key column")
|
|
TEST_VARIATION(13, L"On a column that is part of the index")
|
|
TEST_VARIATION(14, L"On a table that is in another catalog")
|
|
TEST_VARIATION(15, L"Use different combination for update/delete rules, as well as match type")
|
|
TEST_VARIATION(16, L"Referenced table name and base table names have maximum length")
|
|
TEST_VARIATION(17, L"Columns in the foreign key (base table and reference table) have different names")
|
|
TEST_VARIATION(18, L"Different size in column lists (base table and referenced)")
|
|
TEST_VARIATION(19, L"Column types in base table and reference table are different")
|
|
TEST_VARIATION(20, L"Invalid value for the update rule")
|
|
TEST_VARIATION(21, L"Invalid value for the delete rule")
|
|
TEST_VARIATION(22, L"Invalid value for the MatchType")
|
|
TEST_VARIATION(23, L"Inexistent column names in the referenced table")
|
|
TEST_VARIATION(24, L"Inexistent column name in the base table")
|
|
TEST_VARIATION(25, L"Inexistent base table")
|
|
TEST_VARIATION(26, L"Inexistent reference table")
|
|
TEST_VARIATION(27, L"NULL pConstraintID")
|
|
TEST_VARIATION(28, L"Referenced col list is not a unique / pk constraint => failure")
|
|
TEST_VARIATION(29, L"Create a foreign key and then insert a NULL value for one of the fk columns")
|
|
TEST_VARIATION(30, L"The referenced table and the base table are the same")
|
|
TEST_VARIATION(31, L"The base and referenced tables are temporary tables")
|
|
TEST_VARIATION(32, L"Base table is a temporary table")
|
|
TEST_VARIATION(33, L"Abort retaining")
|
|
TEST_VARIATION(34, L"Abort non retaining")
|
|
TEST_VARIATION(35, L"Commit retaining")
|
|
TEST_VARIATION(36, L"Commit non retaining")
|
|
TEST_VARIATION(37, L"The base table is already populated and the referenced one is empty => DB_E_SCHEMAVIOLATION")
|
|
TEST_VARIATION(38, L"Find maximum columns allowed in foreign keys")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAddConstraint_CHECK)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_UNIQUE
|
|
//
|
|
class TCAddConstraint_CHECK : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAddConstraint_CHECK,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Add simple check constraint
|
|
int Variation_1();
|
|
// @cmember Add 2 check constraints on the same column
|
|
int Variation_2();
|
|
// @cmember Add check constraint for each column
|
|
int Variation_3();
|
|
// @cmember Check constraint is always TRUE
|
|
int Variation_4();
|
|
// @cmember Check constraint is always false
|
|
int Variation_5();
|
|
// @cmember Long text for the check constraint
|
|
int Variation_6();
|
|
// @cmember Check constraint is made of white characters
|
|
int Variation_7();
|
|
// @cmember Maximum length for the table name
|
|
int Variation_8();
|
|
// @cmember Create the constraint, drop it, readd it with different text
|
|
int Variation_9();
|
|
// @cmember Use inexistent column names in the check constraint
|
|
int Variation_10();
|
|
// @cmember Use qualified table column with different table
|
|
int Variation_11();
|
|
// @cmember Set a check condition on an index column
|
|
int Variation_12();
|
|
// @cmember pwszConstraintText is NULL
|
|
int Variation_13();
|
|
// @cmember pwszConstraintText is an empty string
|
|
int Variation_14();
|
|
// @cmember Abort retaining
|
|
int Variation_15();
|
|
// @cmember Abort non retaining
|
|
int Variation_16();
|
|
// @cmember Commit retaining
|
|
int Variation_17();
|
|
// @cmember Commit non retaining
|
|
int Variation_18();
|
|
// @cmember Table is populated with rows that break the constraint to be added => DB_E_SCHEMAVIOLATION
|
|
int Variation_19();
|
|
// @cmember Create check constraint in different catalog
|
|
int Variation_20();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAddConstraint_CHECK)
|
|
#define THE_CLASS TCAddConstraint_CHECK
|
|
BEG_TEST_CASE(TCAddConstraint_CHECK, TCITableDefinition, L"Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_UNIQUE")
|
|
TEST_VARIATION(1, L"Add simple check constraint")
|
|
TEST_VARIATION(2, L"Add 2 check constraints on the same column")
|
|
TEST_VARIATION(3, L"Add check constraint for each column")
|
|
TEST_VARIATION(4, L"Check constraint is always TRUE")
|
|
TEST_VARIATION(5, L"Check constraint is always false")
|
|
TEST_VARIATION(6, L"Long text for the check constraint")
|
|
TEST_VARIATION(7, L"Check constraint is made of white characters")
|
|
TEST_VARIATION(8, L"Maximum length for the table name")
|
|
TEST_VARIATION(9, L"Create the constraint, drop it, readd it with different text")
|
|
TEST_VARIATION(10, L"Use inexistent column names in the check constraint")
|
|
TEST_VARIATION(11, L"Use qualified table column with different table")
|
|
TEST_VARIATION(12, L"Set a check condition on an index column")
|
|
TEST_VARIATION(13, L"pwszConstraintText is NULL")
|
|
TEST_VARIATION(14, L"pwszConstraintText is an empty string")
|
|
TEST_VARIATION(15, L"Abort retaining")
|
|
TEST_VARIATION(16, L"Abort non retaining")
|
|
TEST_VARIATION(17, L"Commit retaining")
|
|
TEST_VARIATION(18, L"Commit non retaining")
|
|
TEST_VARIATION(19, L"Table is populated with rows that break the constraint to be added => DB_E_SCHEMAVIOLATION")
|
|
TEST_VARIATION(20, L"Check constraint is created on a table in different catalog")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAddConstraint_Deferrability)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::AddConstraint used with deferrability setting
|
|
//
|
|
class TCAddConstraint_Deferrability : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAddConstraint_Deferrability,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Immediate unique constraint
|
|
int Variation_1();
|
|
// @cmember Defferable unique constraint
|
|
int Variation_2();
|
|
// @cmember Deffered unique constraint
|
|
int Variation_3();
|
|
// @cmember Bad deferrability value unique constraint
|
|
int Variation_4();
|
|
// @cmember Immediate primary key constraint
|
|
int Variation_5();
|
|
// @cmember Deferrable primary key constraint
|
|
int Variation_6();
|
|
// @cmember Deferred primary key constraint
|
|
int Variation_7();
|
|
// @cmember Bad deferrability value primary key constraint
|
|
int Variation_8();
|
|
// @cmember Immediate foreign key constraint
|
|
int Variation_9();
|
|
// @cmember Deferrable foreign key constraint
|
|
int Variation_10();
|
|
// @cmember Deferred foreign key constraint
|
|
int Variation_11();
|
|
// @cmember Bad deferrability value foreign key constraint
|
|
int Variation_12();
|
|
// @cmember Immediate check constraint
|
|
int Variation_13();
|
|
// @cmember Deferrable check constraint
|
|
int Variation_14();
|
|
// @cmember Deferred check constraint
|
|
int Variation_15();
|
|
// @cmember Bad deferrability value check constraint
|
|
int Variation_16();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAddConstraint_Deferrability)
|
|
#define THE_CLASS TCAddConstraint_Deferrability
|
|
BEG_TEST_CASE(TCAddConstraint_Deferrability, TCITableDefinition, L"Testcase for ITableDefinitionWithConstraints::AddConstraint used with deferrability setting")
|
|
TEST_VARIATION(1, L"Immediate unique constraint")
|
|
TEST_VARIATION(2, L"Defferable unique constraint")
|
|
TEST_VARIATION(3, L"Deffered unique constraint")
|
|
TEST_VARIATION(4, L"Bad deferrability value unique constraint")
|
|
TEST_VARIATION(5, L"Immediate primary key constraint")
|
|
TEST_VARIATION(6, L"Deferrable primary key constraint")
|
|
TEST_VARIATION(7, L"Deferred primary key constraint")
|
|
TEST_VARIATION(8, L"Bad deferrability value primary key constraint")
|
|
TEST_VARIATION(9, L"Immediate foreign key constraint")
|
|
TEST_VARIATION(10, L"Deferrable foreign key constraint")
|
|
TEST_VARIATION(11, L"Deferred foreign key constraint")
|
|
TEST_VARIATION(12, L"Bad deferrability value foreign key constraint")
|
|
TEST_VARIATION(13, L"Immediate check constraint")
|
|
TEST_VARIATION(14, L"Deferrable check constraint")
|
|
TEST_VARIATION(15, L"Deferred check constraint")
|
|
TEST_VARIATION(16, L"Bad deferrability value check constraint")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCCreateTableWithConstraints_NoConstraint)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::AddConstraint used with deferrability setting
|
|
//
|
|
class TCCreateTableWithConstraints_NoConstraint : public TCCreateTable {
|
|
public:
|
|
//DECLARE_TEST_CASE_DATA();
|
|
ITableDefinitionWithConstraints *m_pITableDefinitionWithConstraints;
|
|
|
|
public:
|
|
static const WCHAR m_wszTestCaseName[];
|
|
static const WCHAR m_wszTestCaseDesc[];
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCCreateTableWithConstraints_NoConstraint,TCCreateTable);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @member Create the table using ITableDefinition::CreateTable and check its creation
|
|
virtual HRESULT CreateAndCheckTable(
|
|
ITableDefinition *pITableDefinitionWithConstraints, // [in] pointer to the ITableDefinition interface to be used
|
|
IUnknown *pUnkOuter, // [in] pointer to controlling unknown
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBORDINAL cColumnDescs, // [in] the number of columns to be created
|
|
DBCOLUMNDESC *rgColumnDesc, // [in/out] array of columns to be created
|
|
REFIID riid, // [in] rowset interface to be returned
|
|
ULONG cPropertySets, // [in] number of roset property sets asked
|
|
DBPROPSET *rgPropertySets, // [in/out] array of rowset property sets
|
|
DBID **ppTableID, // [out] returned table ID
|
|
IUnknown **ppRowset // [out] pointer to outer interface
|
|
);
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCCreateTableWithConstraints_NoConstraint)
|
|
//#define THE_CLASS TCCreateTableWithConstraints_NoConstraint
|
|
//BEG_TEST_CASE(TCCreateTableWithConstraints_NoConstraint, TCCreateTable, L"Testcase for ITableDefinitionWithConstraints::AddConstraint used with deferrability setting")
|
|
//END_TEST_CASE()
|
|
//#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
const WCHAR TCCreateTableWithConstraints_NoConstraint::m_wszTestCaseName[] = { L"TCCreateTableWithConstraints_NoConstraint" };
|
|
const WCHAR TCCreateTableWithConstraints_NoConstraint::m_wszTestCaseDesc[] = { L"Testcase for ITableDefinitionWithConstraints::CreateTable when no constraints are specified => should expect the same results as for ITableDefinition::CreateTable" };
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCCreateTableWithConstraints)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::CreateTableWithConstraints when constraints are set
|
|
//
|
|
class TCCreateTableWithConstraints : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCCreateTableWithConstraints,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Create a table and multiple constraint of various types
|
|
int Variation_1();
|
|
// @cmember Table with a unique constraint (on a single column)
|
|
int Variation_2();
|
|
// @cmember Table with a unique constraint (on multiple columns)
|
|
int Variation_3();
|
|
// @cmember Table with a primary key constraint (on a single column)
|
|
int Variation_4();
|
|
// @cmember Table with a primary key constraint (on multiple columns)
|
|
int Variation_5();
|
|
// @cmember Table with a foreign key constraint (single column)
|
|
int Variation_6();
|
|
// @cmember Table with foreign key constraint defined on multiple keys
|
|
int Variation_7();
|
|
// @cmember Table with a simple check constraint
|
|
int Variation_8();
|
|
// @cmember Table with multiple unique constraints defined
|
|
int Variation_9();
|
|
// @cmember Table with unique constraint and foreign key
|
|
int Variation_10();
|
|
// @cmember Table with primary key and check constraint
|
|
int Variation_11();
|
|
// @cmember Deferrable, immediate constraints
|
|
int Variation_12();
|
|
// @cmember Deferred constraints
|
|
int Variation_13();
|
|
// @cmember Abort retain
|
|
int Variation_14();
|
|
// @cmember Abort non retain
|
|
int Variation_15();
|
|
// @cmember Commit retain
|
|
int Variation_16();
|
|
// @cmember Commit non retain
|
|
int Variation_17();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCCreateTableWithConstraints)
|
|
#define THE_CLASS TCCreateTableWithConstraints
|
|
BEG_TEST_CASE(TCCreateTableWithConstraints, TCITableDefinition, L"Testcase for ITableDefinitionWithConstraints::CreateTableWithConstraints when constraints are set")
|
|
TEST_VARIATION(1, L"Create a table and multiple constraint of various types")
|
|
TEST_VARIATION(2, L"Table with a unique constraint (on a single column)")
|
|
TEST_VARIATION(3, L"Table with a unique constraint (on multiple columns)")
|
|
TEST_VARIATION(4, L"Table with a primary key constraint (on a single column)")
|
|
TEST_VARIATION(5, L"Table with a primary key constraint (on multiple columns)")
|
|
TEST_VARIATION(6, L"Table with a foreign key constraint (single column)")
|
|
TEST_VARIATION(7, L"Table with foreign key constraint defined on multiple keys")
|
|
TEST_VARIATION(8, L"Table with a simple check constraint")
|
|
TEST_VARIATION(9, L"Table with multiple unique constraints defined")
|
|
TEST_VARIATION(10, L"Table with unique constraint and foreign key")
|
|
TEST_VARIATION(11, L"Table with primary key and check constraint")
|
|
TEST_VARIATION(12, L"Deferrable, immediate constraints")
|
|
TEST_VARIATION(13, L"Deferred constraints")
|
|
TEST_VARIATION(14, L"Abort retain")
|
|
TEST_VARIATION(15, L"Abort non retain")
|
|
TEST_VARIATION(16, L"Commit retain")
|
|
TEST_VARIATION(17, L"Commit non retain")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCCreateTableWithConstraints_Boundary)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Boundary and NULL testcase for ITableDefinitionWithConstraints::CreateTableWithConstraints
|
|
//
|
|
class TCCreateTableWithConstraints_Boundary : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCCreateTableWithConstraints_Boundary,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember 0 < cConstraintDescs and NULL == rgConstraintDescs => E_INVALIDARG
|
|
int Variation_1();
|
|
// @cmember 0 == cConstraintDescs and NULL != rgConstraintDescs => S_OK
|
|
int Variation_2();
|
|
// @cmember pTableID is NULL ppTableID is not NULL => S_OK
|
|
int Variation_3();
|
|
// @cmember Bad DBKIND of a constraint ID
|
|
int Variation_4();
|
|
// @cmember NULL pConstraintID in a constraint
|
|
int Variation_5();
|
|
// @cmember NULL column list in a constraint, column size is not 0 => E_INVALIDARG
|
|
int Variation_6();
|
|
// @cmember Empty list of columns for a unique, primay key or foreign key constraint
|
|
int Variation_7();
|
|
// @cmember Non empty list of columns for a check constraint
|
|
int Variation_8();
|
|
// @cmember Non empty list of foreign keys for a constraint that is not foreign key
|
|
int Variation_9();
|
|
// @cmember 0 < cForeignKeyColumns and NULL == rgForeignKeyColumnList => E_INVALIDARG
|
|
int Variation_10();
|
|
// @cmember Constraint is not foreign key and pReferencedTableID is not NULL
|
|
int Variation_11();
|
|
// @cmember NULL pReferencedTableID for a foreign key constraint (with and without cForeignKeyColumns being 0)
|
|
int Variation_12();
|
|
// @cmember NULL referenced table name for a foreign key constraint
|
|
int Variation_13();
|
|
// @cmember DB_NULLID *pReferencedTableID for a foreign key constraint
|
|
int Variation_14();
|
|
// @cmember Empty string referenced table name for a foreign key constraint
|
|
int Variation_15();
|
|
// @cmember Maximum length referenced table name for a foreign key constraint
|
|
int Variation_16();
|
|
// @cmember Referenced table name longer than allowed for a foreign key constraint
|
|
int Variation_17();
|
|
// @cmember Illegal characters in the referenced table name for a foreign key constraint
|
|
int Variation_18();
|
|
// @cmember Bad constraint type
|
|
int Variation_19();
|
|
// @cmember Inexistent referenced table
|
|
int Variation_20();
|
|
// @cmember Empty string for a column name
|
|
int Variation_21();
|
|
// @cmember Maximum length column name in a constraint
|
|
int Variation_22();
|
|
// @cmember Invalid DBKIND for a column DBID of a constraint
|
|
int Variation_23();
|
|
// @cmember Column ID is DB_NULLID
|
|
int Variation_24();
|
|
// @cmember Inexistent column => DB_E_NOCOLUMN
|
|
int Variation_25();
|
|
// @cmember NULL column name => DB_E_NOCOLUMN
|
|
int Variation_26();
|
|
// @cmember Column name exceeds maximum length name
|
|
int Variation_27();
|
|
// @cmember Invalid column name
|
|
int Variation_28();
|
|
// @cmember Existent table name => DB_E_DUPLICATETABLEID
|
|
int Variation_29();
|
|
// @cmember Same constraint name in 2 constraints => DB_E_DUPLICATECONSTRAINTID
|
|
int Variation_30();
|
|
// @cmember NULL pConstraintID in 2 constraints => S_OK
|
|
int Variation_31();
|
|
// @cmember Try to create table with constraints, but table already exists => DB_E_DUPLICATEDTABLEID
|
|
int Variation_32();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
|
|
// {{ TCW_TESTCASE(TCCreateTableWithConstraints_Boundary)
|
|
#define THE_CLASS TCCreateTableWithConstraints_Boundary
|
|
BEG_TEST_CASE(TCCreateTableWithConstraints_Boundary, TCITableDefinition, L"Boundary and NULL testcase for ITableDefinitionWithConstraints::CreateTableWithConstraints")
|
|
TEST_VARIATION(1, L"0 < cConstraintDescs and NULL == rgConstraintDescs => E_INVALIDARG")
|
|
TEST_VARIATION(2, L"0 == cConstraintDescs and NULL != rgConstraintDescs => S_OK")
|
|
TEST_VARIATION(3, L"pTableID is NULL ppTableID is not NULL => S_OK")
|
|
TEST_VARIATION(4, L"Bad DBKIND of a constraint ID")
|
|
TEST_VARIATION(5, L"NULL pConstraintID in a constraint")
|
|
TEST_VARIATION(6, L"NULL column list in a constraint, column size is not 0 => E_INVALIDARG")
|
|
TEST_VARIATION(7, L"Empty list of columns for a unique, primay key or foreign key constraint")
|
|
TEST_VARIATION(8, L"Non empty list of columns for a check constraint")
|
|
TEST_VARIATION(9, L"Non empty list of foreign keys for a constraint that is not foreign key")
|
|
TEST_VARIATION(10, L"0 < cForeignKeyColumns and NULL == rgForeignKeyColumnList => E_INVALIDARG")
|
|
TEST_VARIATION(11, L"Constraint is not foreign key and pReferencedTableID is not NULL")
|
|
TEST_VARIATION(12, L"NULL pReferencedTableID for a foreign key constraint (with and without cForeignKeyColumns being 0)")
|
|
TEST_VARIATION(13, L"NULL referenced table name for a foreign key constraint")
|
|
TEST_VARIATION(14, L"DB_NULLID *pReferencedTableID for a foreign key constraint")
|
|
TEST_VARIATION(15, L"Empty string referenced table name for a foreign key constraint")
|
|
TEST_VARIATION(16, L"Maximum length referenced table name for a foreign key constraint")
|
|
TEST_VARIATION(17, L"Referenced table name longer than allowed for a foreign key constraint")
|
|
TEST_VARIATION(18, L"Illegal characters in the referenced table name for a foreign key constraint")
|
|
TEST_VARIATION(19, L"Bad constraint type")
|
|
TEST_VARIATION(20, L"Inexistent referenced table")
|
|
TEST_VARIATION(21, L"Empty string for a column name")
|
|
TEST_VARIATION(22, L"Maximum length column name in a constraint")
|
|
TEST_VARIATION(23, L"Invalid DBKIND for a column DBID of a constraint")
|
|
TEST_VARIATION(24, L"Column ID is DB_NULLID")
|
|
TEST_VARIATION(25, L"Inexistent column => DB_E_NOCOLUMN")
|
|
TEST_VARIATION(26, L"NULL column name => DB_E_NOCOLUMN")
|
|
TEST_VARIATION(27, L"Column name exceeds maximum length name")
|
|
TEST_VARIATION(28, L"Invalid column name")
|
|
TEST_VARIATION(29, L"Existent table name => DB_E_DUPLICATETABLEID")
|
|
TEST_VARIATION(30, L"Same constraint name in 2 constraints => DB_E_DUPLICATECONSTRAINTID")
|
|
TEST_VARIATION(31, L"NULL pConstraintID in 2 constraints => S_OK")
|
|
TEST_VARIATION(32, L"Try to create table with constraints, but table already exists => DB_E_DUPLICATEDTABLEID")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCDropConstraint)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::DropConstraint
|
|
//
|
|
class TCDropConstraint : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCDropConstraint,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember pTableID is NULL => E_INVALIDARG
|
|
int Variation_1();
|
|
// @cmember pTableID.uName.pwszName is NULL => DB_E_BADTABLEID
|
|
int Variation_2();
|
|
// @cmember Table name is empty => DB_E_BADTABLEID
|
|
int Variation_3();
|
|
// @cmember Table name is not the one on which the column was created
|
|
int Variation_4();
|
|
// @cmember Inexistent table name => DB_E_NOTABLE
|
|
int Variation_5();
|
|
// @cmember Maximum table name => S_OK
|
|
int Variation_6();
|
|
// @cmember Invalid characters in table's name => DB_E_BADTABLEID
|
|
int Variation_7();
|
|
// @cmember pConstraintID is NUL => E_INVALIDARG
|
|
int Variation_8();
|
|
// @cmember *pConstraintID is DB_NULLID => DB_E_NOCONSTRAINT
|
|
int Variation_9();
|
|
// @cmember Invalid DBKIND in the constraint name => DB_E_NOCONSTRAINT
|
|
int Variation_10();
|
|
// @cmember NULL constraint name => DB_E_NOCONSTRAINT
|
|
int Variation_11();
|
|
// @cmember Constraint name is empty string => DB_E_NOCONSTRAINT
|
|
int Variation_12();
|
|
// @cmember Inexistent constraint name => DB_E_NOCONSTRAINT
|
|
int Variation_13();
|
|
// @cmember Drop a constraint twice
|
|
int Variation_14();
|
|
// @cmember Drop a unique constraint
|
|
int Variation_15();
|
|
// @cmember Drop a primary key constraint
|
|
int Variation_16();
|
|
// @cmember Drop a foreign key constraint
|
|
int Variation_17();
|
|
// @cmember Drop a check constraint
|
|
int Variation_18();
|
|
// @cmember Create several constraints, drop a single constraint
|
|
int Variation_19();
|
|
// @cmember Drop a unique constraint in the referenced table, after the foreign key constraint was added
|
|
int Variation_20();
|
|
// @cmember Try to drop a unique constraint while a rowset is opened on the table => DB_E_TABLEINUSE
|
|
int Variation_21();
|
|
// @cmember *pTableID is DB_NULLID => DB_E_BADTABLEID
|
|
int Variation_22();
|
|
// @cmember Invalid DBKIND in pTableID => DB_E_BADTABLEID
|
|
int Variation_23();
|
|
// @cmember Try to drop a check constraint while a rowset is opened on the table => DB_E_TABLEINUSE
|
|
int Variation_24();
|
|
// @cmember Try to drop a pk constraint while a rowset is opened on the table => DB_E_TABLEINUSE
|
|
int Variation_25();
|
|
// @cmember Try to drop a fk constraint while a rowset is opened on the table => DB_E_TABLEINUSE
|
|
int Variation_26();
|
|
// @cmember Both pTableID and pConstraintID are NULL => E_INVALIDARG
|
|
int Variation_27();
|
|
// @cmember Abort retain
|
|
int Variation_28();
|
|
// @cmember Abort non retain
|
|
int Variation_29();
|
|
// @cmember Commit retain
|
|
int Variation_30();
|
|
// @cmember Commit non retain
|
|
int Variation_31();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCDropConstraint)
|
|
#define THE_CLASS TCDropConstraint
|
|
BEG_TEST_CASE(TCDropConstraint, TCITableDefinition, L"Testcase for ITableDefinitionWithConstraints::DropConstraint")
|
|
TEST_VARIATION(1, L"pTableID is NULL => E_INVALIDARG")
|
|
TEST_VARIATION(2, L"pTableID.uName.pwszName is NULL => DB_E_BADTABLEID")
|
|
TEST_VARIATION(3, L"Table name is empty => DB_E_BADTABLEID")
|
|
TEST_VARIATION(4, L"Table name is not the one on which the column was created")
|
|
TEST_VARIATION(5, L"Inexistent table name => DB_E_NOTABLE")
|
|
TEST_VARIATION(6, L"Maximum table name => S_OK")
|
|
TEST_VARIATION(7, L"Invalid characters in table's name => DB_E_BADTABLEID")
|
|
TEST_VARIATION(8, L"pConstraintID is NUL => E_INVALIDARG")
|
|
TEST_VARIATION(9, L"*pConstraintID is DB_NULLID => DB_E_NOCONSTRAINT")
|
|
TEST_VARIATION(10, L"Invalid DBKIND in the constraint name => DB_E_NOCONSTRAINT")
|
|
TEST_VARIATION(11, L"NULL constraint name => DB_E_NOCONSTRAINT")
|
|
TEST_VARIATION(12, L"Constraint name is empty string => DB_E_NOCONSTRAINT")
|
|
TEST_VARIATION(13, L"Inexistent constraint name => DB_E_NOCONSTRAINT")
|
|
TEST_VARIATION(14, L"Drop a constraint twice")
|
|
TEST_VARIATION(15, L"Drop a unique constraint")
|
|
TEST_VARIATION(16, L"Drop a primary key constraint")
|
|
TEST_VARIATION(17, L"Drop a foreign key constraint")
|
|
TEST_VARIATION(18, L"Drop a check constraint")
|
|
TEST_VARIATION(19, L"Create several constraints, drop a single constraint")
|
|
TEST_VARIATION(20, L"Drop a unique constraint in the referenced table, after the foreign key constraint was added")
|
|
TEST_VARIATION(21, L"Try to drop a unique constraint while a rowset is opened on the table => DB_E_TABLEINUSE")
|
|
TEST_VARIATION(22, L"*pTableID is DB_NULLID => DB_E_BADTABLEID")
|
|
TEST_VARIATION(23, L"Invalid DBKIND in pTableID => DB_E_BADTABLEID")
|
|
TEST_VARIATION(24, L"Try to drop a check constraint while a rowset is opened on the table => DB_E_TABLEINUSE")
|
|
TEST_VARIATION(25, L"Try to drop a pk constraint while a rowset is opened on the table => DB_E_TABLEINUSE")
|
|
TEST_VARIATION(26, L"Try to drop a fk constraint while a rowset is opened on the table => DB_E_TABLEINUSE")
|
|
TEST_VARIATION(27, L"Both pTableID and pConstraintID are NULL => E_INVALIDARG")
|
|
TEST_VARIATION(28, L"Abort retain")
|
|
TEST_VARIATION(29, L"Abort non retain")
|
|
TEST_VARIATION(30, L"Commit retain")
|
|
TEST_VARIATION(31, L"Commit non retain")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAddConstraint_Multithreading)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Testcase for ITableDefinitionWithConstraints::AddConstraint used in multithreaded calls
|
|
//
|
|
class TCAddConstraint_Multithreading : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
DBID **m_prgTableID;
|
|
DBCONSTRAINTDESC *m_rgConstraintDesc;
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAddConstraint_Multithreading,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Each thread creates a different constraint
|
|
int Variation_1();
|
|
// @cmember Some of the threads try to create the same constraint name
|
|
int Variation_2();
|
|
// @cmember Unique constraints with disjoint columns
|
|
int Variation_3();
|
|
// @cmember Unique constraints with overlapping columns
|
|
int Variation_4();
|
|
// @cmember All constraint IDs are generated by the provider
|
|
int Variation_5();
|
|
// }} TCW_TESTVARS_END
|
|
|
|
unsigned MyThreadProc(ULONG i);
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAddConstraint_Multithreading)
|
|
#define THE_CLASS TCAddConstraint_Multithreading
|
|
BEG_TEST_CASE(TCAddConstraint_Multithreading, TCITableDefinition, L"Testcase for ITableDefinitionWithConstraints::AddConstraint used in multithreaded calls")
|
|
TEST_VARIATION(1, L"Each thread creates a different constraint")
|
|
TEST_VARIATION(2, L"Some of the threads try to create the same constraint name")
|
|
TEST_VARIATION(3, L"Unique constraints with disjoint columns")
|
|
TEST_VARIATION(4, L"Unique constraints with overlapping columns")
|
|
TEST_VARIATION(5, L"All constraint IDs are generated by the provider")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCDropConstraint_Multithreading)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Multithreading test case for ITableDefinitionWithConstraints::DropConstraints
|
|
//
|
|
class TCDropConstraint_Multithreading : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
DBID **m_prgTableID;
|
|
DBID **m_prgConstraintID;
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCDropConstraint_Multithreading,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Each thread drops a different constraint => all S_OK
|
|
int Variation_1();
|
|
// @cmember Some threads try to drop the same constraint => S_OK and DB_E_NOCONSTRAINT
|
|
int Variation_2();
|
|
// }} TCW_TESTVARS_END
|
|
|
|
unsigned MyThreadProc(ULONG i);
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCDropConstraint_Multithreading)
|
|
#define THE_CLASS TCDropConstraint_Multithreading
|
|
BEG_TEST_CASE(TCDropConstraint_Multithreading, TCITableDefinition, L"Multithreading test case for ITableDefinitionWithConstraints::DropConstraints")
|
|
TEST_VARIATION(1, L"Each thread drops a different constraint => all S_OK")
|
|
TEST_VARIATION(2, L"Some threads try to drop the same constraint => S_OK and DB_E_NOCONSTRAINT")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCCreateTableWithConstraints_Multithreading)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Multithreading test case for ITableDefinitionWithConstraints::CreateTableWithConstraints
|
|
//
|
|
class TCCreateTableWithConstraints_Multithreading : public TCITableDefinition {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
CCTWCThreadParam *m_rgThreadParams;
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCCreateTableWithConstraints_Multithreading,TCITableDefinition);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Each thread builds different table => all S_OK
|
|
int Variation_1();
|
|
// @cmember Some threads build the same table => S_OK and DB_E_DUPLICATETABLEID
|
|
int Variation_2();
|
|
// }} TCW_TESTVARS_END
|
|
|
|
unsigned MyThreadProc(ULONG i);
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCCreateTableWithConstraints_Multithreading)
|
|
#define THE_CLASS TCCreateTableWithConstraints_Multithreading
|
|
BEG_TEST_CASE(TCCreateTableWithConstraints_Multithreading, TCITableDefinition, L"Multithreading test case for ITableDefinitionWithConstraints::CreateTableWithConstraints")
|
|
TEST_VARIATION(1, L"Each thread builds different table => all S_OK")
|
|
TEST_VARIATION(2, L"Some threads build the same table => S_OK and DB_E_DUPLICATETABLEID")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// }} END_DECLARE_TEST_CASES()
|
|
|
|
|
|
// {{ TCW_TESTMODULE(ThisModule)
|
|
TEST_MODULE(18, ThisModule, gwszModuleDescrip)
|
|
TEST_CASE(1, TCAddColumn)
|
|
TEST_CASE(2, TCDropColumn)
|
|
TEST_CASE(3, TCDropTable)
|
|
TEST_CASE(4, TCCreateTable)
|
|
TEST_CASE(5, RODataSource)
|
|
TEST_CASE(6, TCAddConstraint_Boundary)
|
|
TEST_CASE(7, TCAddConstraint_UNIQUE)
|
|
TEST_CASE(8, TCAddConstraint_PRIMARYKEY)
|
|
TEST_CASE(9, TCAddConstraint_FOREIGNKEY)
|
|
TEST_CASE(10, TCAddConstraint_CHECK)
|
|
TEST_CASE(11, TCAddConstraint_Deferrability)
|
|
TEST_CASE(12, TCCreateTableWithConstraints_NoConstraint)
|
|
TEST_CASE(13, TCCreateTableWithConstraints)
|
|
TEST_CASE(14, TCCreateTableWithConstraints_Boundary)
|
|
TEST_CASE(15, TCDropConstraint)
|
|
TEST_CASE(16, TCAddConstraint_Multithreading)
|
|
TEST_CASE(17, TCDropConstraint_Multithreading)
|
|
TEST_CASE(18, TCCreateTableWithConstraints_Multithreading)
|
|
END_TEST_MODULE()
|
|
// }} TCW_TESTMODULE_END
|
|
|
|
|
|
class CTransactionAdapter {
|
|
public:
|
|
CTransactionAdapter() {}
|
|
~CTransactionAdapter() {}
|
|
|
|
virtual BOOL BeforeTransaction() = 0;
|
|
virtual HRESULT InsideTransactionScope() = 0;
|
|
virtual HRESULT InsideTransactionOnDDLLock() = 0;
|
|
virtual BOOL CheckCompletion() = 0;
|
|
virtual BOOL CheckRollBack() = 0;
|
|
}; //class CTransactionAdapter
|
|
|
|
|
|
class CAddConstraintTxnAdapter: public CTransactionAdapter {
|
|
protected:
|
|
TCITableDefinition *m_pTCITableDefinition;
|
|
CTable m_Table;
|
|
CConstraints *m_pConstraints;
|
|
CConsDesc *m_pCons;
|
|
// m_TransactedTable will be created inside the transaction
|
|
CTable m_TransactedTable;
|
|
// constraint on transacted table
|
|
CConsDesc *m_pTransactedTableCons;
|
|
CConstraints *m_pTxnConstraints;
|
|
|
|
public:
|
|
CAddConstraintTxnAdapter(TCITableDefinition *pTCITableDefinition) :
|
|
CTransactionAdapter(),
|
|
m_pTCITableDefinition(pTCITableDefinition),
|
|
m_pConstraints(NULL), m_pCons(NULL),
|
|
m_Table(g_pIOpenRowset, (LPWSTR)gwszModuleName),
|
|
m_TransactedTable(g_pIOpenRowset, (LPWSTR)gwszModuleName),
|
|
m_pTransactedTableCons(NULL),
|
|
m_pTxnConstraints(NULL)
|
|
{}
|
|
~CAddConstraintTxnAdapter() {
|
|
m_Table.DropTable();
|
|
m_TransactedTable.DropTable();
|
|
delete m_pConstraints;
|
|
delete m_pCons;
|
|
delete m_pTransactedTableCons;
|
|
delete m_pTxnConstraints;
|
|
}
|
|
|
|
|
|
TCITableDefinition *pTCITableDefinition() {return m_pTCITableDefinition;}
|
|
virtual BOOL BeforeTransaction();
|
|
|
|
virtual HRESULT InsideTransactionScope() {
|
|
return m_pTCITableDefinition->AddConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_Table.GetTableID(), *m_pCons);
|
|
}
|
|
virtual HRESULT InsideTransactionOnDDLLock() {
|
|
return m_pTCITableDefinition->pITDWC()->AddConstraint(
|
|
&m_Table.GetTableID(), *m_pCons);
|
|
}
|
|
|
|
virtual BOOL CheckCompletion() {
|
|
TBEGIN
|
|
BOOL fTableExisted;
|
|
ASSERT(m_pCons);
|
|
CHECK(m_pConstraints->CheckAddConstraints(1, *m_pCons), S_OK);
|
|
|
|
// transacted table exists
|
|
ASSERT(m_pTransactedTableCons);
|
|
CHECK(m_TransactedTable.DoesTableExist(&m_TransactedTable.GetTableID(), &fTableExisted), S_OK);
|
|
COMPARE(fTableExisted, TRUE);
|
|
CHECK(m_pTxnConstraints->CheckAddConstraints(1, *m_pTransactedTableCons), S_OK);
|
|
TRETURN
|
|
}
|
|
virtual BOOL CheckRollBack() {
|
|
TBEGIN
|
|
BOOL fTableExisted;
|
|
|
|
ASSERT(m_pCons);
|
|
CHECK(m_pConstraints->AreConstraintsPreserved(), S_OK);
|
|
|
|
// transacted table does not exist
|
|
ASSERT(m_pTransactedTableCons);
|
|
CHECK(m_TransactedTable.DoesTableExist(&m_TransactedTable.GetTableID(), &fTableExisted), S_OK);
|
|
COMPARE(fTableExisted, FALSE);
|
|
CHECK(m_pTxnConstraints->AreConstraintsPreserved(), S_OK);
|
|
TRETURN
|
|
}
|
|
}; //class CAddConstraintTxnAdapter
|
|
|
|
|
|
|
|
class CAddUniqueConsTxnAdapter: public CAddConstraintTxnAdapter {
|
|
public:
|
|
CAddUniqueConsTxnAdapter(TCITableDefinition *pTCITableDefinition):
|
|
CAddConstraintTxnAdapter(pTCITableDefinition) {}
|
|
~CAddUniqueConsTxnAdapter() {
|
|
}
|
|
|
|
virtual BOOL BeforeTransaction();
|
|
virtual HRESULT InsideTransactionScope();
|
|
virtual HRESULT InsideTransactionOnDDLLock();
|
|
virtual BOOL CheckCompletion();
|
|
virtual BOOL CheckRollBack();
|
|
}; //class CAddUniqueConsTxnAdapter
|
|
|
|
|
|
|
|
class CAddPrimaryKeyConsTxnAdapter: public CAddUniqueConsTxnAdapter {
|
|
public:
|
|
CAddPrimaryKeyConsTxnAdapter(TCITableDefinition *pTCITableDefinition):
|
|
CAddUniqueConsTxnAdapter(pTCITableDefinition)
|
|
{}
|
|
~CAddPrimaryKeyConsTxnAdapter() {
|
|
}
|
|
|
|
virtual BOOL BeforeTransaction();
|
|
}; //class CAddPrimaryKeyConsTxnAdapter
|
|
|
|
|
|
|
|
class CAddFKConsTxnAdapter: public CAddConstraintTxnAdapter {
|
|
private:
|
|
CTable m_ReferencedTable;
|
|
|
|
public:
|
|
CAddFKConsTxnAdapter(TCITableDefinition *pTCITableDefinition):
|
|
CAddConstraintTxnAdapter(pTCITableDefinition),
|
|
m_ReferencedTable(g_pIOpenRowset, (LPWSTR)gwszModuleName)
|
|
{}
|
|
~CAddFKConsTxnAdapter() {
|
|
m_Table.DropTable();
|
|
m_TransactedTable.DropTable();
|
|
m_ReferencedTable.DropTable();
|
|
}
|
|
|
|
virtual BOOL BeforeTransaction();
|
|
virtual HRESULT InsideTransactionScope();
|
|
virtual HRESULT InsideTransactionOnDDLLock();
|
|
virtual BOOL CheckCompletion();
|
|
virtual BOOL CheckRollBack();
|
|
}; //class CAddFKConsTxnAdapter
|
|
|
|
|
|
|
|
class CAddCheckConsTxnAdapter: public CAddConstraintTxnAdapter {
|
|
public:
|
|
CAddCheckConsTxnAdapter(TCITableDefinition *pTCITableDefinition):
|
|
CAddConstraintTxnAdapter(pTCITableDefinition)
|
|
{}
|
|
~CAddCheckConsTxnAdapter() {}
|
|
|
|
virtual BOOL BeforeTransaction();
|
|
virtual HRESULT InsideTransactionScope();
|
|
virtual HRESULT InsideTransactionOnDDLLock();
|
|
virtual BOOL CheckCompletion();
|
|
virtual BOOL CheckRollBack();
|
|
}; //class CAddCheckConsTxnAdapter
|
|
|
|
|
|
|
|
class CCreateTableWithConsTxnAdapter: public CTransactionAdapter {
|
|
protected:
|
|
TCITableDefinition *m_pTCITableDefinition;
|
|
CTable m_Table;
|
|
CConstraints *m_pConstraints;
|
|
CConsDescArray m_ConsDescArray;
|
|
// m_TransactedTable will be created inside the transaction
|
|
CTable m_RefTable;
|
|
DBORDINAL m_cColumnDesc;
|
|
DBCOLUMNDESC *m_rgColumnDesc;
|
|
|
|
public:
|
|
CCreateTableWithConsTxnAdapter(TCITableDefinition *pTCITableDefinition) :
|
|
CTransactionAdapter(),
|
|
m_pTCITableDefinition(pTCITableDefinition),
|
|
m_pConstraints(NULL),
|
|
m_Table(g_pIOpenRowset, (LPWSTR)gwszModuleName),
|
|
m_RefTable(g_pIOpenRowset, (LPWSTR)gwszModuleName),
|
|
m_cColumnDesc(0), m_rgColumnDesc(NULL)
|
|
{}
|
|
~CCreateTableWithConsTxnAdapter() {
|
|
m_Table.DropTable();
|
|
m_RefTable.DropTable();
|
|
delete m_pConstraints;
|
|
m_pConstraints = NULL;
|
|
ReleaseColumnDesc(m_rgColumnDesc, m_cColumnDesc);
|
|
}
|
|
|
|
|
|
TCITableDefinition *pTCITableDefinition() {return m_pTCITableDefinition;}
|
|
virtual BOOL BeforeTransaction();
|
|
|
|
virtual HRESULT InsideTransactionScope() {
|
|
return m_pTCITableDefinition->CreateAndCheckTableWithConstraints(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
NULL,
|
|
&m_Table.GetTableID(),
|
|
m_cColumnDesc,
|
|
m_rgColumnDesc,
|
|
m_ConsDescArray,
|
|
m_ConsDescArray,
|
|
IID_NULL,
|
|
0, NULL,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
virtual HRESULT InsideTransactionOnDDLLock() {
|
|
return m_pTCITableDefinition->pITDWC()->CreateTableWithConstraints(
|
|
NULL, &m_Table.GetTableID(),
|
|
m_cColumnDesc,
|
|
m_rgColumnDesc,
|
|
m_ConsDescArray,
|
|
m_ConsDescArray,
|
|
IID_NULL,
|
|
0, NULL,
|
|
NULL,
|
|
NULL);
|
|
}
|
|
|
|
virtual BOOL CheckCompletion() {
|
|
TBEGIN
|
|
BOOL fTableExisted;
|
|
|
|
// check constraints were added
|
|
CHECK(m_pConstraints->CheckAddConstraints(m_ConsDescArray, m_ConsDescArray), S_OK);
|
|
|
|
// transacted table exists
|
|
CHECK(m_Table.DoesTableExist(&m_Table.GetTableID(), &fTableExisted), S_OK);
|
|
COMPARE(fTableExisted, TRUE);
|
|
TRETURN
|
|
}
|
|
virtual BOOL CheckRollBack() {
|
|
TBEGIN
|
|
BOOL fTableExisted;
|
|
|
|
CHECK(m_pConstraints->AreConstraintsPreserved(), S_OK);
|
|
// transacted table does not exist
|
|
CHECK(m_Table.DoesTableExist(&m_Table.GetTableID(), &fTableExisted), S_OK);
|
|
COMPARE(fTableExisted, FALSE);
|
|
TRETURN
|
|
}
|
|
}; //class CCreateTableWithConsTxnAdapter
|
|
|
|
|
|
|
|
class CDropConsTxnAdapter: public CTransactionAdapter {
|
|
protected:
|
|
TCITableDefinition *m_pTCITableDefinition;
|
|
CTable m_Table;
|
|
CTable m_RefTable;
|
|
CConstraints *m_pConstraints;
|
|
CPrimaryKeyCons *m_pPKCons;
|
|
CForeignKeyCons *m_pFKCons;
|
|
CUniqueCons *m_pUniqueCons;
|
|
CCheckCons *m_pCheckCons;
|
|
|
|
public:
|
|
CDropConsTxnAdapter(TCITableDefinition *pTCITableDefinition) :
|
|
CTransactionAdapter(),
|
|
m_pTCITableDefinition(pTCITableDefinition),
|
|
m_pConstraints(NULL),
|
|
m_Table(g_pIOpenRowset, (LPWSTR)gwszModuleName),
|
|
m_RefTable(g_pIOpenRowset, (LPWSTR)gwszModuleName),
|
|
m_pPKCons(NULL), m_pFKCons(NULL), m_pUniqueCons(NULL), m_pCheckCons(NULL)
|
|
{}
|
|
~CDropConsTxnAdapter() {
|
|
m_Table.DropTable();
|
|
m_RefTable.DropTable();
|
|
delete m_pConstraints;
|
|
delete m_pPKCons;
|
|
delete m_pFKCons;
|
|
delete m_pUniqueCons;
|
|
delete m_pCheckCons;
|
|
}
|
|
|
|
|
|
TCITableDefinition *pTCITableDefinition() {return m_pTCITableDefinition;}
|
|
virtual BOOL BeforeTransaction();
|
|
|
|
virtual HRESULT InsideTransactionScope() {
|
|
HRESULT hr = S_OK;
|
|
HRESULT hres;
|
|
|
|
hres = m_pTCITableDefinition->DropConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_Table.GetTableID(), *m_pPKCons);
|
|
hr = (S_OK == hr)? hres: hr;
|
|
|
|
hres = m_pTCITableDefinition->DropConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_Table.GetTableID(), *m_pFKCons);
|
|
hr = (S_OK == hr)? hres: hr;
|
|
|
|
hres = m_pTCITableDefinition->DropConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_Table.GetTableID(), *m_pUniqueCons);
|
|
hr = (S_OK == hr)? hres: hr;
|
|
|
|
hres = m_pTCITableDefinition->DropConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_Table.GetTableID(), *m_pCheckCons);
|
|
hr = (S_OK == hr)? hres: hr;
|
|
|
|
return hr;
|
|
}
|
|
virtual HRESULT InsideTransactionOnDDLLock() {
|
|
HRESULT hr = S_OK;
|
|
HRESULT hres;
|
|
|
|
hres = m_pTCITableDefinition->pITDWC()->DropConstraint(
|
|
&m_Table.GetTableID(), *m_pPKCons);
|
|
hr = (S_OK == hr)? hres: hr;
|
|
|
|
hres = m_pTCITableDefinition->pITDWC()->DropConstraint(
|
|
&m_Table.GetTableID(), *m_pFKCons);
|
|
hr = (S_OK == hr)? hres: hr;
|
|
|
|
hres = m_pTCITableDefinition->pITDWC()->DropConstraint(
|
|
&m_Table.GetTableID(), *m_pUniqueCons);
|
|
hr = (S_OK == hr)? hres: hr;
|
|
|
|
hres = m_pTCITableDefinition->pITDWC()->DropConstraint(
|
|
&m_Table.GetTableID(), *m_pCheckCons);
|
|
hr = (S_OK == hr)? hres: hr;
|
|
|
|
return hr;
|
|
}
|
|
|
|
virtual BOOL CheckCompletion() {
|
|
TBEGIN
|
|
|
|
ASSERT(m_pPKCons);
|
|
ASSERT(m_pFKCons);
|
|
ASSERT(m_pUniqueCons);
|
|
ASSERT(m_pCheckCons);
|
|
CHECK(m_pConstraints->CheckDropConstraint(*m_pPKCons), S_OK);
|
|
CHECK(m_pConstraints->CheckDropConstraint(*m_pFKCons), S_OK);
|
|
CHECK(m_pConstraints->CheckDropConstraint(*m_pUniqueCons), S_OK);
|
|
CHECK(m_pConstraints->CheckDropConstraint(*m_pCheckCons), S_OK);
|
|
TRETURN
|
|
}
|
|
virtual BOOL CheckRollBack() {
|
|
TBEGIN
|
|
ASSERT(m_pPKCons);
|
|
ASSERT(m_pFKCons);
|
|
ASSERT(m_pUniqueCons);
|
|
ASSERT(m_pCheckCons);
|
|
CHECK(m_pConstraints->AreConstraintsPreserved(), S_OK);
|
|
TRETURN
|
|
}
|
|
}; //class CDropConsTxnAdapter
|
|
|
|
|
|
|
|
|
|
class CTransactionLocal {
|
|
protected:
|
|
CLightDataSource m_DataSource;
|
|
CLightSession m_Session;
|
|
LONG m_lSupportedTxnDDL;
|
|
CTransactionAdapter *m_pTAdapter;
|
|
|
|
public:
|
|
CTransactionLocal(
|
|
) {
|
|
m_pTAdapter = NULL;
|
|
m_lSupportedTxnDDL = DBPROPVAL_TC_NONE;
|
|
}
|
|
|
|
~CTransactionLocal() { }
|
|
|
|
virtual HRESULT StartTransaction(
|
|
IUnknown *pISessionUnknown,
|
|
// arguments for ITransactionLocal::StartTransaction
|
|
ISOLEVEL isoLevel,
|
|
ULONG isoFlags,
|
|
ITransactionOptions *pOtherOptions
|
|
);
|
|
virtual HRESULT Abort(
|
|
BOID * pboidReason,
|
|
BOOL fRetaining,
|
|
BOOL fAsync
|
|
) {
|
|
return ((ITransactionLocal*)m_Session)->Abort(pboidReason, fRetaining, fAsync);
|
|
}
|
|
virtual HRESULT Commit(
|
|
BOOL fRetaining,
|
|
DWORD grfTC,
|
|
DWORD grfRM
|
|
) {
|
|
return ((ITransactionLocal*)m_Session)->Commit(fRetaining, grfTC, grfRM);
|
|
}
|
|
|
|
virtual BOOL DoTransactionTest(
|
|
IUnknown *pISessionUnknown,
|
|
CTransactionAdapter *pTAdapter,
|
|
// arguments for ITransactionLocal::Abort / Commit
|
|
BOOL fDDL, // whether or not this is a DDL call
|
|
BOOL fAbortCommit, // whether to abort or commit
|
|
BOOL fRetaining // if it's retaining or not
|
|
);
|
|
|
|
}; //CTransactionLocal
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Initialize the TCIDefinition data members
|
|
//---------------------------------------------------------------------
|
|
BOOL TCITableDefinition::Init()
|
|
{
|
|
m_pITDWC = NULL;
|
|
m_pITableDefinition = NULL;
|
|
m_nTables = 0;
|
|
|
|
InitializeCriticalSection(&m_CriticalSection);
|
|
if(CSessionObject::Init())
|
|
{
|
|
SetDataSourceObject(m_pThisTestModule->m_pIUnknown);
|
|
SetDBSession(m_pThisTestModule->m_pIUnknown2);
|
|
// select ITableDefinition as standard table creation method
|
|
GetModInfo()->UseITableDefinition(TRUE);
|
|
GetProviderTypes();
|
|
GetLiteralInfo();
|
|
m_nTables = GetNoOfTables();
|
|
m_pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
|
|
// check for ITableDefinition
|
|
if (!(m_hr=VerifyInterface(m_pIOpenRowset, IID_ITableDefinition, SESSION_INTERFACE, (IUnknown**)&m_pITableDefinition)))
|
|
return FALSE;
|
|
|
|
m_pIOpenRowset->QueryInterface(IID_ITableDefinitionWithConstraints, (void**)&m_pITDWC);
|
|
|
|
if (m_pITDWC)
|
|
{
|
|
// find out what values of matching types are supported for foreign keys
|
|
DBORDINAL rgCol[] = {1};
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable Table2(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
HRESULT hr;
|
|
|
|
TESTC_(Table.CreateTable(0, 1), S_OK);
|
|
CHECK(Table.AddInfoFromColumnsSchemaRowset(m_pITableDefinition), S_OK);
|
|
TESTC_(Table2.CreateTable(0, 1), S_OK);
|
|
CHECK(Table2.AddInfoFromColumnsSchemaRowset(m_pITableDefinition), S_OK);
|
|
|
|
m_SupportedMatchType = DBMATCHTYPE_NONE;
|
|
TEST2C_(hr = AddForeignKeyConstraint(&Table, NUMELEM(rgCol), rgCol, &Table2, NUMELEM(rgCol), rgCol,
|
|
m_SupportedMatchType), S_OK, DB_E_BADMATCHTYPE);
|
|
|
|
if (S_OK != hr)
|
|
{
|
|
m_SupportedMatchType = DBMATCHTYPE_PARTIAL;
|
|
TEST2C_(hr = AddForeignKeyConstraint(&Table, NUMELEM(rgCol), rgCol, &Table2, NUMELEM(rgCol), rgCol,
|
|
m_SupportedMatchType), S_OK, DB_E_BADMATCHTYPE);
|
|
|
|
if (S_OK != hr)
|
|
{
|
|
m_SupportedMatchType = DBMATCHTYPE_FULL;
|
|
TESTC_(hr = AddForeignKeyConstraint(&Table, NUMELEM(rgCol), rgCol, &Table2, NUMELEM(rgCol), rgCol,
|
|
m_SupportedMatchType), S_OK);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
Table2.DropTable();
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember constructor
|
|
//---------------------------------------------------------------------
|
|
TCITableDefinition::TCITableDefinition(WCHAR *wstrTestCaseName):CSessionObject(wstrTestCaseName)
|
|
{
|
|
m_fIsIDBInfo = NULL;
|
|
m_pwszInvalidTableChars = NULL;
|
|
m_pwszInvalidColChars = NULL;
|
|
m_pITableDefinition = NULL;
|
|
m_rgColumnDesc = NULL;
|
|
m_cColumnDesc = 0;
|
|
} //TCITableDefinition::TCITableDefinition
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
//
|
|
// @cmember Compare two column in the identical position
|
|
//-------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::AreColEqual
|
|
(
|
|
DBCOLUMNDESC *oldCD,
|
|
DBCOLUMNDESC *newCD
|
|
)
|
|
{
|
|
// when this function is called, it is supposed that m_HasAuto... were set by GetTableColumnInfo
|
|
// and unmodified ever since
|
|
ULONG cPropSet, cProp;
|
|
BOOL fResult = FALSE;
|
|
DBPROPSET *pNewPropSet = NULL;
|
|
DBPROPSET *pOldPropSet = NULL;
|
|
DBPROP *pNewProp = NULL;
|
|
DBPROP *pOldProp = NULL;
|
|
|
|
// compare everything in the stru
|
|
ASSERT(oldCD->pTypeInfo == newCD->pTypeInfo);
|
|
TESTC(oldCD->pTypeInfo == newCD->pTypeInfo);
|
|
TESTC(oldCD->ulColumnSize == newCD->ulColumnSize);
|
|
TESTC(oldCD->wType == newCD->wType);
|
|
TESTC(!IsNumericType(oldCD->wType) || oldCD->bPrecision == newCD->bPrecision);
|
|
TESTC( (oldCD->wType != DBTYPE_NUMERIC && oldCD->wType != DBTYPE_DECIMAL)
|
|
|| oldCD->bScale == newCD->bScale);
|
|
TESTC(m_hr = CompareDBID(oldCD->dbcid, newCD->dbcid, m_pIDBInitialize));
|
|
|
|
// invalidated for the time being
|
|
// if the CLSID are to be compared for the lists, then a GUID object has to be allocated and mentained;
|
|
// during the life of each ColumnDescriptor array
|
|
// if a pointer to m_gTypeGUID of a column is stored we'll have troubles as soon as the value of the column changes
|
|
//if (m_pTable->GetHasCLSID() && !CHECK(oldCD->pclsid == newCD->pclsid, TRUE))
|
|
// return FALSE;
|
|
|
|
// compare the properties
|
|
TESTC(oldCD->cPropertySets == newCD->cPropertySets);
|
|
|
|
for (cPropSet=0; cPropSet<oldCD->cPropertySets; cPropSet++)
|
|
{
|
|
pOldPropSet = &(oldCD->rgPropertySets[cPropSet]);
|
|
pNewPropSet = &(newCD->rgPropertySets[cPropSet]);
|
|
|
|
// compare the props in that prop set
|
|
TESTC(pOldPropSet->guidPropertySet == pNewPropSet->guidPropertySet);
|
|
TESTC(pOldPropSet->cProperties == pNewPropSet->cProperties);
|
|
|
|
for (cProp = 0; cProp < pOldPropSet->cProperties; cProp++)
|
|
{
|
|
pOldProp = &(pOldPropSet->rgProperties[cProp]);
|
|
pNewProp = &(pNewPropSet->rgProperties[cProp]);
|
|
|
|
// there are no info for some of the properties
|
|
if ( ((pNewProp->dwPropertyID == DBPROP_COL_AUTOINCREMENT) && !m_pTable->GetHasAuto())
|
|
|| ((pNewProp->dwPropertyID == DBPROP_COL_DEFAULT) && !m_pTable->GetHasDefault())
|
|
|| ((pNewProp->dwPropertyID == DBPROP_COL_UNIQUE) && !m_pTable->GetHasUnique())
|
|
)
|
|
continue;
|
|
|
|
TESTC(pOldProp->dwPropertyID == pNewProp->dwPropertyID);
|
|
TESTC(CompareVariant(&(pOldProp->vValue), &(pNewProp->vValue)));
|
|
}
|
|
}
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
} //TCITableDefinition::AreColEqual
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
//
|
|
// @cmember Compare the list of old columns against the list of new columns
|
|
//-------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::AreColEqual
|
|
(
|
|
DBCOLUMNDESC *oldCD,
|
|
DBORDINAL oldlen,
|
|
DBCOLUMNDESC *newCD,
|
|
DBORDINAL newlen
|
|
)
|
|
{
|
|
// when this function is called, it is supposed that m_HasAuto... were set by GetTableColumnInfo
|
|
// and unmodified ever since
|
|
ULONG i;
|
|
BOOL fResult = FALSE;
|
|
|
|
TESTC(oldlen == newlen);
|
|
|
|
for (i=0; i<oldlen; i++)
|
|
{
|
|
TESTC(AreColEqual(&newCD[i], &oldCD[i]));
|
|
}
|
|
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
} //TCITableDefinition::AreColEqual
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Check the result and property status
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::CheckPropertyStatus(
|
|
GUID guidPropertySet, // [in] property set guid
|
|
GUID guidExpectedPS, // [in] expected prop set guid
|
|
DBPROP *pProp , // [in] property
|
|
HRESULT hr // [in] the result
|
|
)
|
|
{
|
|
BOOL fRes = TRUE;
|
|
BOOL fSupported;
|
|
BOOL fSettable;
|
|
VARTYPE vtType;
|
|
|
|
if (!pProp)
|
|
return TRUE;
|
|
|
|
// general checking
|
|
if (DBPROPOPTIONS_REQUIRED == pProp->dwOptions && DBPROPSTATUS_OK != pProp->dwStatus)
|
|
fRes = COMPARE(FAILED(hr), TRUE);
|
|
|
|
if (!(guidPropertySet == guidExpectedPS) )
|
|
// check a couple of things and returns
|
|
return COMPARE(pProp->dwStatus, DBPROPSTATUS_NOTSUPPORTED) && COMPARE(S_OK != hr, TRUE);
|
|
|
|
fSupported = SupportedProperty(pProp->dwPropertyID, guidPropertySet);
|
|
fSettable = SettableProperty(pProp->dwPropertyID, guidPropertySet);
|
|
|
|
if (!fSupported && !COMPARE(S_OK != hr, TRUE))
|
|
fRes = FALSE;
|
|
|
|
// status driven checking
|
|
switch (pProp->dwStatus)
|
|
{
|
|
case DBPROPSTATUS_OK:
|
|
fRes = COMPARE(fSupported != 0, TRUE);
|
|
break;
|
|
case DBPROPSTATUS_NOTSUPPORTED:
|
|
fRes = COMPARE(fSupported == 0, TRUE);
|
|
break;
|
|
case DBPROPSTATUS_NOTSETTABLE:
|
|
fRes = COMPARE(fSupported != 0, TRUE) && CHECK(fSettable == 0, TRUE);
|
|
break;
|
|
case DBPROPSTATUS_BADOPTION:
|
|
fRes = (pProp->dwOptions != DBPROPOPTIONS_OPTIONAL)
|
|
&& COMPARE(DBPROPOPTIONS_REQUIRED != pProp->dwOptions, TRUE);
|
|
break;
|
|
case DBPROPSTATUS_CONFLICTING:
|
|
fRes = COMPARE(fSettable != 0, TRUE);
|
|
break;
|
|
case DBPROPSTATUS_BADVALUE:
|
|
// this could mean not supported property or value
|
|
break;
|
|
}
|
|
|
|
// DBPROPSTATUS_BADVALUE can be certainly got only if type of the prop is wrong
|
|
// info about supported discret values of the prop cannot be generacally obtained
|
|
// before creating an index
|
|
vtType = GetPropInfoType(pProp->dwPropertyID, guidPropertySet);
|
|
if ( DBPROP_COL_DEFAULT != pProp->dwPropertyID
|
|
&& vtType != pProp->vValue.vt
|
|
&& !COMPARE(DBPROPSTATUS_OK == pProp->dwStatus, FALSE))
|
|
{
|
|
odtLog << "ERROR: bad propstatus on improper type value on property" << pProp->dwPropertyID << "\n";
|
|
fRes = FALSE;
|
|
}
|
|
|
|
return fRes;
|
|
} //TCITableDefinition::CheckProperty
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
//
|
|
// @cmember Check the prop status of a list of col desc
|
|
// returns TRUE if all status are set consistent with prop and result
|
|
// FALSE otherwise
|
|
//--------------------------------------------------------------------
|
|
BOOL TCITableDefinition::CheckColPropStatus(
|
|
DBORDINAL cColDesc, // [in]
|
|
DBCOLUMNDESC *rgColDesc, // [in] the size of the propset array
|
|
HRESULT hr // [in] the result of the previous op
|
|
)
|
|
{
|
|
ULONG cPropSet;
|
|
ULONG cProp;
|
|
BOOL fRes = TRUE;
|
|
DBORDINAL nCol;
|
|
|
|
if (!rgColDesc)
|
|
return TRUE;
|
|
|
|
for (nCol = 0; nCol < cColDesc; nCol++)
|
|
{
|
|
if (!rgColDesc[nCol].rgPropertySets)
|
|
continue;
|
|
for (cPropSet = 0; cPropSet < rgColDesc[nCol].cPropertySets; cPropSet++)
|
|
{
|
|
if (!rgColDesc[nCol].rgPropertySets[cPropSet].rgProperties)
|
|
continue;
|
|
for (cProp = 0; cProp < rgColDesc[nCol].rgPropertySets[cPropSet].cProperties; cProp++)
|
|
{
|
|
fRes = fRes && CheckPropertyStatus(rgColDesc[nCol].rgPropertySets[cPropSet].guidPropertySet,
|
|
DBPROPSET_COLUMN, &rgColDesc[nCol].rgPropertySets[cPropSet].rgProperties[cProp], hr);
|
|
}
|
|
}
|
|
}
|
|
return fRes;
|
|
} // TCITableDefinition::CheckColPropStatus
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
//
|
|
// @cmember CompareColumnDesc
|
|
// pColumnDesc and pNewCol [IN] parameteres to be compared
|
|
// column addition (table creation) is assumed to have succeeded
|
|
// returns TRUE or FALSE
|
|
//--------------------------------------------------------------------
|
|
BOOL TCITableDefinition::CompareColumnDesc(
|
|
DBCOLUMNDESC *pColumnDesc, // [in] column descriptor, as passed to ITableDefinition::AddColumn()
|
|
DBCOLUMNDESC *pNewCol // [in] column descriptor, as read from the table after addition
|
|
)
|
|
{
|
|
DBPROPSET *pNewPropSet = NULL;
|
|
DBPROPSET *pInPropSet = NULL;
|
|
DBPROP *pInProp = NULL;
|
|
ULONG j;
|
|
ULONG cPropSet, cProp;
|
|
ULONG n;
|
|
POSITION pos, posOld, posFind;
|
|
CCol col;
|
|
BOOL fRes = FALSE;
|
|
GUID gCD;
|
|
|
|
TESTC(pColumnDesc->pTypeInfo == pNewCol->pTypeInfo);
|
|
|
|
PRVTRACE("TCITableDefinition::CompareColumnDesc: pColumnDesc->wType = %d, pNewCol->wType = %d\n",
|
|
pColumnDesc->wType, pNewCol->wType);
|
|
TESTC(pColumnDesc->wType == pNewCol->wType);
|
|
|
|
TESTC(CompareDBID(pColumnDesc->dbcid, pNewCol->dbcid, m_pIDBInitialize));
|
|
|
|
// if there is a provider type name, the column size, precision and
|
|
// scale of the column can be checked otherwise skip it there could
|
|
// be several provider types implemented on the DBTYPE
|
|
if (!pColumnDesc->pwszTypeName)
|
|
{
|
|
// are multiple provider types implemented on the same DBTYPE?
|
|
for (posFind = pos = m_ColList.GetHeadPosition(), n=0; pos;)
|
|
{
|
|
posOld = pos;
|
|
col = m_ColList.GetNext(pos);
|
|
if (col.GetProviderType() == pNewCol->wType)
|
|
{
|
|
n++;
|
|
posFind = posOld;
|
|
}
|
|
}
|
|
col = m_ColList.GetAt(posFind);
|
|
}
|
|
else
|
|
{
|
|
BOOL fExistType;
|
|
col = GetType(GetColumnTypeName(pColumnDesc), pNewCol->wType, &fExistType);
|
|
n = fExistType ? 1: 0;
|
|
}
|
|
|
|
// see if there are enough data for a compColumnDescrison
|
|
if (1 != n)
|
|
{
|
|
fRes = TRUE;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// CHECK THE COLUMN SIZE
|
|
|
|
// for DBTYPE_STR, DBTYPE_WSTR, DBTYPE_BSTR check whether the
|
|
// size of the column fits with the spec ones or the maximum
|
|
if ((pNewCol->wType == DBTYPE_STR) ||
|
|
(pNewCol->wType == DBTYPE_WSTR) ||
|
|
(pNewCol->wType == DBTYPE_BYTES) )
|
|
{
|
|
LPWSTR pwszCreateParams = col.GetCreateParams();
|
|
if (col.GetColumnSize() >= pColumnDesc->ulColumnSize)
|
|
{
|
|
if ( 0 != pColumnDesc->ulColumnSize
|
|
&& pwszCreateParams
|
|
&& NULL != wcsstr(pwszCreateParams, L"length"))
|
|
TESTC(pColumnDesc->ulColumnSize == pNewCol->ulColumnSize);
|
|
}
|
|
else
|
|
{
|
|
// Check for varchar(max), nvarchar(max), and varbinary(max) types
|
|
if ((pColumnDesc->pwszTypeName &&
|
|
(wcscmp(pColumnDesc->pwszTypeName, L"varchar") == 0 ||
|
|
wcscmp(pColumnDesc->pwszTypeName, L"nvarchar") == 0 ||
|
|
wcscmp(pColumnDesc->pwszTypeName, L"varbinary") == 0))
|
|
|
|
||
|
|
|
|
(pNewCol->wType == DBTYPE_WSTR || pNewCol->wType == DBTYPE_BYTES)
|
|
)
|
|
{
|
|
//Note: we need to verify column size as read from the table after column addition (pNewCol),
|
|
TESTC(pNewCol->ulColumnSize == ~(DBLENGTH)0);
|
|
}
|
|
else
|
|
// column size should be set to the max column size allowed
|
|
TESTC(col.GetColumnSize() == pNewCol->ulColumnSize);
|
|
}
|
|
}
|
|
else
|
|
if (!IsFixedLength(pNewCol->wType) && DBTYPE_VARNUMERIC != pNewCol->wType)
|
|
TESTC(pNewCol->ulColumnSize == (DBLENGTH)~0);
|
|
|
|
// CHECK THE PRECISION
|
|
if (IsNumericType(pColumnDesc->wType) || DBTYPE_DBTIMESTAMP == pColumnDesc->wType)
|
|
{
|
|
if (0 < pColumnDesc->bPrecision)
|
|
if ( DBTYPE_NUMERIC == pColumnDesc->wType
|
|
|| DBTYPE_VARNUMERIC == pColumnDesc->wType )
|
|
{
|
|
if (DBTYPE_VARNUMERIC != pColumnDesc->wType ) //
|
|
TESTC(pColumnDesc->bPrecision == pNewCol->bPrecision);
|
|
}
|
|
else
|
|
TESTC(col.GetPrecision() == pNewCol->bPrecision);
|
|
}
|
|
else
|
|
TESTC(pNewCol->bPrecision == (BYTE)~0);
|
|
|
|
|
|
// CHECK SCALE
|
|
if ( DBTYPE_NUMERIC == pColumnDesc->wType
|
|
|| DBTYPE_VARNUMERIC == pColumnDesc->wType
|
|
|| DBTYPE_DECIMAL == pColumnDesc->wType
|
|
|| DBTYPE_DBTIMESTAMP == pColumnDesc->wType)
|
|
{
|
|
if (DBTYPE_VARNUMERIC != pColumnDesc->wType )
|
|
if ( DBTYPE_DBTIMESTAMP != pColumnDesc->wType
|
|
&& pColumnDesc->bScale >= col.GetMinScale()
|
|
&& pColumnDesc->bScale > col.GetMaxScale())
|
|
TESTC(pColumnDesc->bScale == pNewCol->bScale);
|
|
}
|
|
else
|
|
TESTC(pNewCol->bScale == (BYTE)~0); // as set trhough col.SetColInfo
|
|
|
|
// get the psid
|
|
if (pColumnDesc->pclsid)
|
|
gCD = *pColumnDesc->pclsid;
|
|
else
|
|
gCD = GUID_NULL;
|
|
|
|
TESTC(!m_pTable->GetHasCLSID() || gCD == *(GUID*)pNewCol->pclsid);
|
|
|
|
if (NULL == pColumnDesc->rgPropertySets)
|
|
{
|
|
fRes = TRUE;
|
|
goto CLEANUP;
|
|
}
|
|
for (cPropSet=0; cPropSet<(pColumnDesc->cPropertySets); cPropSet++)
|
|
{
|
|
pInPropSet = &(pColumnDesc->rgPropertySets[cPropSet]);
|
|
|
|
if ( pInPropSet->guidPropertySet != DBPROPSET_COLUMN )
|
|
{
|
|
for (cProp=0; cProp < pInPropSet->cProperties; cProp++)
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == pInPropSet->rgProperties[cProp].dwStatus);
|
|
continue;
|
|
}
|
|
|
|
// Find matching PropSet
|
|
for(j = 0; j < pNewCol->cPropertySets &&
|
|
pNewCol->rgPropertySets[j].guidPropertySet != pInPropSet->guidPropertySet; j++);
|
|
if (j >= pNewCol->cPropertySets)
|
|
continue;
|
|
|
|
pNewPropSet = &(pNewCol->rgPropertySets[j]);
|
|
|
|
// compColumnDescre the propPropSet in the column prop set
|
|
ASSERT(pNewPropSet->rgProperties);
|
|
if (NULL == pInPropSet->rgProperties)
|
|
continue;
|
|
for (cProp=0; cProp < pInPropSet->cProperties; cProp++)
|
|
{
|
|
pInProp = &(pInPropSet->rgProperties[cProp]);
|
|
|
|
if (pInPropSet->guidPropertySet == DBPROPSET_COLUMN)
|
|
{
|
|
|
|
// look for that property inside the resulted column
|
|
if (((pInProp->dwPropertyID == DBPROP_COL_AUTOINCREMENT) && !m_pTable->GetHasAuto() ) ||
|
|
((pInProp->dwPropertyID == DBPROP_COL_DEFAULT) && !m_pTable->GetHasDefault() ) ||
|
|
((pInProp->dwPropertyID == DBPROP_COL_UNIQUE) && !m_pTable->GetHasUnique()) )
|
|
// better check the status, it should be DBPROPSTATUS_NOTSUPPORTED
|
|
continue;
|
|
|
|
TESTC( SupportedProperty(pInProp->dwPropertyID, pInPropSet->guidPropertySet)
|
|
|| DBPROPSTATUS_NOTSUPPORTED == pInProp->dwStatus);
|
|
TESTC( SettableProperty(pInProp->dwPropertyID, pInPropSet->guidPropertySet)
|
|
|| DBPROPSTATUS_NOTSUPPORTED == pInProp->dwStatus);
|
|
|
|
// identify the property
|
|
for ( j=0;
|
|
j< pNewPropSet->cProperties
|
|
&& pNewPropSet->rgProperties[j].dwPropertyID != pInProp->dwPropertyID;
|
|
j++);
|
|
|
|
if (j>=pNewPropSet->cProperties)
|
|
continue;
|
|
|
|
// try to detect the right dbpropstatus
|
|
TESTC( (DBPROPSTATUS_OK != pInProp->dwStatus)
|
|
|| CompareVariant(&pInProp->vValue, &pNewPropSet->rgProperties[j].vValue));
|
|
}
|
|
// skipping the testing of other provider-specific property sets
|
|
}
|
|
}
|
|
fRes = TRUE;
|
|
|
|
CLEANUP:
|
|
return fRes;
|
|
} //TCITableDefinition::CompColumnDescreColumnDesc
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
//
|
|
// @cmember Compare the list of old columns against the list of new columns and the new column
|
|
// the place where the newly added column was added is provider specific!
|
|
//--------------------------------------------------------------------
|
|
BOOL TCITableDefinition::CheckColInfo
|
|
(
|
|
DBCOLUMNDESC *oldCD,
|
|
DBORDINAL oldlen,
|
|
DBCOLUMNDESC *newCD,
|
|
DBORDINAL newlen,
|
|
DBCOLUMNDESC *pColumnDesc // the new column to be add
|
|
)
|
|
{
|
|
// when this function is called, it is supposed that m_HasAuto... were set by GetTableColumnInfo
|
|
// and unmodified ever since
|
|
BOOL fNewColumn = FALSE;
|
|
BOOL fResult = FALSE;
|
|
DBORDINAL cOldCol;
|
|
DBORDINAL cNewCol;
|
|
|
|
TESTC(newlen == oldlen+1);
|
|
|
|
for (cOldCol=cNewCol=0; cNewCol<newlen; cNewCol++)
|
|
{
|
|
if ( (cOldCol < oldlen)
|
|
&& CompareDBID(oldCD[cOldCol].dbcid, newCD[cNewCol].dbcid, m_pIDBInitialize))
|
|
{
|
|
TESTC(AreColEqual(&oldCD[cOldCol], &newCD[cNewCol]));
|
|
cOldCol++;
|
|
}
|
|
else
|
|
{
|
|
TESTC(!fNewColumn);
|
|
TESTC(CompareColumnDesc(pColumnDesc, &newCD[cOldCol]));
|
|
fNewColumn = TRUE;
|
|
}
|
|
}
|
|
fResult = TRUE;
|
|
|
|
CLEANUP:
|
|
return fResult;
|
|
} //TCITableDefinition::CheckColInfo
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember TCITableDefinition::CheckRowset
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::CheckRowset(IUnknown *pIRowset)
|
|
{
|
|
IRowsetInfo* pInterface = NULL;
|
|
BOOL hr;
|
|
|
|
if (!pIRowset)
|
|
return TRUE;
|
|
|
|
if (hr = DefaultObjectTesting(pIRowset, ROWSET_INTERFACE))
|
|
{
|
|
// just for curiosity
|
|
if (VerifyInterface( pIRowset,
|
|
IID_IRowsetInfo,
|
|
ROWSET_INTERFACE,
|
|
(IUnknown**)&pInterface))
|
|
{
|
|
IUnknown* tempInterface;
|
|
if (pInterface->GetSpecification(IID_IUnknown, &tempInterface) == S_FALSE)
|
|
{
|
|
// what if table ID doesn't specify a name?
|
|
PRVTRACE(L"** No object has created the rowset");
|
|
}
|
|
else
|
|
{
|
|
IUnknown *pIID;
|
|
if (tempInterface->QueryInterface(IID_IGetDataSource, (void**)&pIID) == S_OK)
|
|
{
|
|
PRVTRACE(L"** Rowset was created by a session");
|
|
SAFE_RELEASE(pIID);
|
|
}
|
|
else
|
|
PRVTRACE(L"** Rowset was created by a command");
|
|
SAFE_RELEASE(tempInterface);
|
|
}
|
|
SAFE_RELEASE(pInterface);
|
|
}
|
|
}
|
|
return hr;
|
|
} //CTable::CheckRowset
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Fills in a variant with whatever it needs
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::FillVariant(VARIANT *pVariant)
|
|
{
|
|
BOOL fRes = FALSE;
|
|
BSTR pwszValue = L"\'some value\'";
|
|
WCHAR *pwszStrValue = L"\'value\'";
|
|
|
|
|
|
TESTC(NULL != pVariant);
|
|
switch (pVariant->vt)
|
|
{
|
|
case DBTYPE_R4:
|
|
V_R4(pVariant) = (float)3.1415926;
|
|
break;
|
|
case DBTYPE_R8:
|
|
V_R8(pVariant) = 2.71828;
|
|
break;
|
|
case DBTYPE_BSTR:
|
|
V_BSTR(pVariant) = SysAllocString(pwszValue);
|
|
break;
|
|
case DBTYPE_STR:
|
|
case DBTYPE_WSTR:
|
|
pVariant->vt = DBTYPE_BSTR;
|
|
V_BSTR(pVariant) = SysAllocString(pwszStrValue);
|
|
break;
|
|
case DBTYPE_BYTES:
|
|
V_BYREF(pVariant) = SysAllocString(pwszStrValue);
|
|
break;
|
|
}
|
|
fRes = TRUE;
|
|
|
|
CLEANUP:
|
|
return fRes;
|
|
} // TCITableDefinition::FillVariant
|
|
|
|
|
|
|
|
|
|
// @cmember Builds a default value for a given column type
|
|
BOOL TCITableDefinition::GetDefaultValue(
|
|
DBCOLUMNDESC *pColumnDesc, // [in] column descriptor
|
|
VARIANT *pVariant, // [out] pointer to the variant that stores the default value
|
|
CTable *pTable // [in] CTable to be used (default NULL)
|
|
)
|
|
{
|
|
TBEGIN
|
|
CTable *pCTable = NULL;
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
CCol col;
|
|
WCHAR *pwszDefVal = NULL;
|
|
ULONG ulRowNum = 28;
|
|
HRESULT hr;
|
|
|
|
TESTC(NULL != pColumnDesc); // && NULL != pColumnDesc->pwszTypeName);
|
|
TESTC(NULL != pVariant);
|
|
|
|
VariantInit(pVariant);
|
|
|
|
if (pTable)
|
|
pCTable = pTable;
|
|
else
|
|
{
|
|
pCTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
pCTable->CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
}
|
|
|
|
pCTable->GetColInfo(col, GetColumnTypeName(pColumnDesc));
|
|
|
|
SAFE_ALLOC(pwszDefVal, WCHAR, MAXDATALEN);
|
|
|
|
pwszDefVal[0]=L'\0';
|
|
TESTC_(hr = col.MakeData(pwszDefVal,ulRowNum,PRIMARY,NONULLS), S_OK);
|
|
|
|
pVariant->vt = DBTYPE_BSTR; //col.GetProviderType();
|
|
V_BSTR(pVariant) = SysAllocString(pwszDefVal);
|
|
SAFE_FREE(pwszDefVal);
|
|
|
|
// Use the US_English LCID first and then the System LCID
|
|
hr=VariantChangeTypeEx(pVariant, pVariant, MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), VARIANT_NOVALUEPROP, col.GetProviderType());
|
|
if(S_OK != hr)
|
|
hr=VariantChangeTypeEx(pVariant, pVariant, GetSystemDefaultLCID(), VARIANT_NOVALUEPROP, col.GetProviderType());
|
|
|
|
if (S_OK != hr)
|
|
{
|
|
// try to set it as a VT_BSTR value
|
|
VariantClear(pVariant);
|
|
TESTC_(pCTable->GetLiteralAndValue(col, &pwszDefVal, ulRowNum, col.GetColNum(), PRIMARY), S_OK);
|
|
pVariant->vt = DBTYPE_BSTR;
|
|
V_BSTR(pVariant) = SysAllocString(pwszDefVal);
|
|
TEST2C_(hr, DISP_E_BADVARTYPE, DISP_E_TYPEMISMATCH);
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszDefVal);
|
|
if (!pTable)
|
|
delete pCTable;
|
|
TRETURN
|
|
} // TCITableDefinition::GetDefaultValue
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Get the number of tables in a data sources, base on IDBSchemaRowset
|
|
//--------------------------------------------------------------------------
|
|
ULONG TCITableDefinition::GetNoOfTables()
|
|
{
|
|
IDBSchemaRowset *pInterface = NULL;
|
|
IRowset *pRowset = NULL;
|
|
DBCOUNTITEM n=0;
|
|
HROW * prghRows = NULL;
|
|
|
|
if (!VerifyInterface(m_pIOpenRowset,IID_IDBSchemaRowset, SESSION_INTERFACE, (IUnknown**)&pInterface))
|
|
{
|
|
PRVTRACE(L"** I could not get a pointer to IDBSchemaRowset interface");
|
|
return 0;
|
|
}
|
|
|
|
TESTC_(pInterface->GetRowset(NULL, DBSCHEMA_TABLES, 0, NULL, IID_IRowset, 0, NULL, (IUnknown**)&pRowset), S_OK);
|
|
|
|
TEST2C_(pRowset->GetNextRows(0, 0, LONG_MAX/1024, &n, &prghRows), DB_S_ENDOFROWSET, DB_S_ROWLIMITEXCEEDED );
|
|
|
|
TESTC_(pRowset->ReleaseRows(n, prghRows, NULL, NULL, NULL), S_OK)
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pRowset);
|
|
SAFE_RELEASE(pInterface);
|
|
PROVIDER_FREE(prghRows);
|
|
// I dont't expect the number of tables to exceed ULONG_MAX
|
|
ASSERT(n < ULONG_MAX);
|
|
return (ULONG)n;
|
|
} //TCITableDefinition::GetNoOfTables
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
//
|
|
// @cmember Drops a column and check the result against reallity
|
|
//----------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::DropColumnAndCheck(
|
|
DBID *pTableID, // [in] the table ID
|
|
DBID *pColumnID, // [in] the ID of the column to be dropped
|
|
ITableDefinition *pITableDefinition,/*=NULL*/ // [in] pointer to ITableDefinition interface
|
|
DBID *pBaseTableID/*=NULL*/ // [in] if pTableID is exotic (e.g. fuly qualified) this
|
|
// table id is used to get metadata info about the table
|
|
)
|
|
{
|
|
DBCOLUMNDESC *OldColList = NULL, *NewColList = NULL;
|
|
DBORDINAL oldlen = 0, newlen = 0;
|
|
ULONG i;
|
|
LONG nCol = -1L;
|
|
HRESULT hr;
|
|
BOOL fTableExists = FALSE;
|
|
BOOL fColumnExists = FALSE;
|
|
IOpenRowset *pIOpenRowset = NULL;
|
|
IColumnsInfo *pIColumnsInfo = NULL;
|
|
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_NOCOLUMN,
|
|
DB_E_DROPRESTRICTED,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
HRESULT rgValidHResMDAC25[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_BADCOLUMNID,
|
|
DB_E_DROPRESTRICTED,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION,
|
|
};
|
|
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
|
|
|
|
if (!pBaseTableID)
|
|
pBaseTableID = pTableID;
|
|
|
|
if (!pITableDefinition)
|
|
pITableDefinition = m_pITableDefinition;
|
|
|
|
// check whether the table and column exist
|
|
if (pTableID)
|
|
{
|
|
TESTC(VerifyInterface(pITableDefinition, IID_IOpenRowset, SESSION_INTERFACE, (IUnknown**)&pIOpenRowset));
|
|
TEST2C_(hr = pIOpenRowset->OpenRowset(NULL, pTableID, NULL, IID_IColumnsInfo,
|
|
0, NULL, (IUnknown**)&pIColumnsInfo), S_OK, DB_E_NOTABLE);
|
|
SAFE_RELEASE(pIOpenRowset);
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
fTableExists = S_OK == hr;
|
|
}
|
|
else
|
|
fTableExists = FALSE;
|
|
|
|
|
|
// this function is based on the current table name
|
|
if (fTableExists)
|
|
{
|
|
GetColumnDescOnTable(pBaseTableID, &OldColList, &oldlen);
|
|
if (pColumnID)
|
|
{
|
|
for (fColumnExists = FALSE, i=0; !fColumnExists && (i<oldlen); i++)
|
|
{
|
|
if (CompareDBID(OldColList[i].dbcid, *pColumnID, m_pIDBInitialize))
|
|
fColumnExists = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// the CHECK will be done at the caller level, where the expected return is known
|
|
if ( (hr = m_pITableDefinition->DropColumn(pTableID, pColumnID)) != S_OK)
|
|
{
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
// check that the result is one of the expected results
|
|
TESTC(CheckResult(hr, cValidHRes, g_fSQLOLEDB25 ? rgValidHResMDAC25 : rgValidHRes));
|
|
|
|
// call failed
|
|
if (fTableExists) //pTableID && pTableID->uName.pwszName)
|
|
{
|
|
GetColumnDescOnTable(pBaseTableID, &NewColList, &newlen);
|
|
TESTC(AreColEqual(NewColList, newlen, OldColList, oldlen));
|
|
if (!fColumnExists)
|
|
{
|
|
TESTC_(hr, pColumnID? (g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN): E_INVALIDARG);
|
|
}
|
|
else
|
|
{
|
|
HRESULT rgValidHRes[] = {DB_E_DROPRESTRICTED, DB_E_TABLEINUSE, DB_SEC_E_PERMISSIONDENIED, XACT_E_XTIONEXISTS, E_FAIL};
|
|
|
|
// check the possible results
|
|
TESTC(CheckResult(hr, NUMELEM(rgValidHRes), rgValidHRes));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pTableID)
|
|
{
|
|
TEST2C_(hr, DB_E_NOTABLE, (g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN));
|
|
}
|
|
else
|
|
TESTC_(hr, E_INVALIDARG);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// call succeeded
|
|
TESTC(fColumnExists);
|
|
GetColumnDescOnTable(pBaseTableID, &NewColList, &newlen);
|
|
for (i = 0, nCol = -1; i < oldlen && nCol < 0; i++)
|
|
{
|
|
if (CompareDBID(OldColList[i].dbcid, *pColumnID, m_pIDBInitialize))
|
|
nCol = (ULONG)i;
|
|
}
|
|
|
|
TESTC(0 <= nCol);
|
|
|
|
// this should work even when the column name is not in the original (old) table
|
|
TESTC(CheckColInfo(NewColList, newlen, OldColList, oldlen, &OldColList[nCol]));
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIOpenRowset);
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
ReleaseColumnDesc(OldColList, oldlen);
|
|
ReleaseColumnDesc(NewColList, newlen);
|
|
return hr;
|
|
} // TCITableDefinition::DropColumnAndCheck
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Drops a table and check the operation
|
|
//--------------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::DropTableAndCheck(
|
|
DBID *pTableID, // [in] ID of the table to be dropped
|
|
ITableDefinition *pITableDefinition /*=NULL*/ // [in] pointer to ITableDefinition interface
|
|
)
|
|
{
|
|
BOOL fExists;
|
|
BOOL fTableExisted;
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
HRESULT hRes;
|
|
|
|
ASSERT(pTable);
|
|
if (!pITableDefinition)
|
|
pITableDefinition = m_pITableDefinition;
|
|
|
|
// check whether the table existed before
|
|
CHECK(pTable->DoesTableExist(pTableID, &fTableExisted), S_OK);
|
|
|
|
// drop the table
|
|
hRes = pITableDefinition->DropTable(pTableID);
|
|
|
|
// check that if table was dropped it doesn't exist
|
|
TESTC(fTableExisted || !SUCCEEDED(hRes));
|
|
TESTC_(pTable->DoesTableExist(pTableID, &fExists), S_OK);
|
|
TESTC(!fTableExisted || fExists == !SUCCEEDED(hRes));
|
|
|
|
CLEANUP:
|
|
delete pTable;
|
|
return hRes;
|
|
} //TCITableDefinition::DropTableAndCheck
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// GetInfo about table identifiers
|
|
//--------------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::GetLiteralInfo()
|
|
{
|
|
IDBInfo* pInterface = NULL;
|
|
DBLITERAL rgLiteral[2]={DBLITERAL_TABLE_NAME, DBLITERAL_COLUMN_NAME};
|
|
DBLITERALINFO* rgLiteralInfo = NULL;
|
|
ULONG cLiteralInfo, i;
|
|
OLECHAR* pCharBuffer = NULL;
|
|
IGetDataSource* pIGetDataSource=NULL; // IGetDataSource interface pointer
|
|
|
|
m_fIsIDBInfo = FALSE;
|
|
|
|
if(!VerifyInterface(m_pIOpenRowset, IID_IGetDataSource, SESSION_INTERFACE, (IUnknown**)&pIGetDataSource))
|
|
return E_FAIL;
|
|
|
|
m_hr=pIGetDataSource->GetDataSource(IID_IDBInfo,(IUnknown**)&pInterface);
|
|
SAFE_RELEASE(pIGetDataSource);
|
|
|
|
if (!CHECK(pInterface->GetLiteralInfo(2, rgLiteral, &cLiteralInfo, &rgLiteralInfo, &pCharBuffer), S_OK))
|
|
goto CLEANUP;
|
|
|
|
for (i=0; i< cLiteralInfo; i++)
|
|
{
|
|
switch (rgLiteralInfo[i].lt)
|
|
{
|
|
case DBLITERAL_TABLE_NAME:
|
|
// get the maximum size of a valid table name and the invalid chars for a table name
|
|
m_cMaxTableName = rgLiteralInfo[i].cchMaxLen;
|
|
PROVIDER_FREE(m_pwszInvalidTableChars);
|
|
m_pwszInvalidTableChars = wcsDuplicate(rgLiteralInfo[i].pwszInvalidChars?
|
|
rgLiteralInfo[i].pwszInvalidChars: L"");
|
|
break;
|
|
case DBLITERAL_COLUMN_NAME:
|
|
m_cMaxColName = rgLiteralInfo[i].cchMaxLen;
|
|
PROVIDER_FREE(m_pwszInvalidColChars);
|
|
m_pwszInvalidColChars = wcsDuplicate(rgLiteralInfo[i].pwszInvalidChars?
|
|
rgLiteralInfo[i].pwszInvalidChars: L"");
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_fIsIDBInfo = TRUE;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pInterface);
|
|
PROVIDER_FREE(pCharBuffer);
|
|
PROVIDER_FREE(rgLiteralInfo);
|
|
return m_hr;
|
|
} //TCITableDefinition::GetLiteralInfo
|
|
|
|
|
|
|
|
|
|
|
|
// @cmember Gets the catalog and schema name for a given table
|
|
BOOL TCITableDefinition::GetCatalogSchemaNames(
|
|
LPWSTR pwszTableName, // [in] the name of the table
|
|
LPWSTR *ppwszCatalogName, // [out] catalog name
|
|
LPWSTR *ppwszSchemaName, // [out] schema name
|
|
CTable *pTable // [in] table object (DEFAULT NULL - use m_pTable)
|
|
)
|
|
{
|
|
IRowset *pIRowset = NULL;
|
|
HROW hRow = DB_NULL_HROW;
|
|
BOOL bFound = FALSE;
|
|
WCHAR *pwszTableName1 = NULL;
|
|
CRowset Rowset;
|
|
|
|
if (!pTable)
|
|
pTable = m_pTable;
|
|
TESTC(NULL != pwszTableName);
|
|
TESTC(NULL != ppwszCatalogName);
|
|
TESTC(NULL != ppwszSchemaName);
|
|
|
|
//Obtain Schema TABLES Rowset
|
|
//We don't want to put any restrictions, since its not required to support
|
|
//restrictions...
|
|
TESTC_PROVIDER((Rowset.CreateRowset(SELECT_DBSCHEMA_TABLE,
|
|
IID_IRowset, pTable, DBACCESSOR_ROWDATA, DBPART_ALL, ALL_COLS_BOUND)==S_OK));
|
|
|
|
//Try to find the specified row with this table...
|
|
while(!bFound && S_OK == (m_hr = Rowset.GetNextRows(&hRow)))
|
|
{
|
|
//GetData for this row
|
|
TESTC_(Rowset.GetRowData(hRow, &Rowset.m_pData),S_OK);
|
|
|
|
//TABLE_NAME column
|
|
DBBINDING* pCatalogBinding = Rowset.m_rgBinding[0].iOrdinal == 0 ? &Rowset.m_rgBinding[1] : &Rowset.m_rgBinding[0];
|
|
DBBINDING* pSchemaBinding = Rowset.m_rgBinding[0].iOrdinal == 0 ? &Rowset.m_rgBinding[2] : &Rowset.m_rgBinding[1];
|
|
DBBINDING* pTableBinding = Rowset.m_rgBinding[0].iOrdinal == 0 ? &Rowset.m_rgBinding[3] : &Rowset.m_rgBinding[2];
|
|
|
|
//See if this is the correct row...
|
|
if(STATUS_BINDING(*pTableBinding, Rowset.m_pData)==DBSTATUS_S_OK)
|
|
{
|
|
//TableName
|
|
pwszTableName1 = (WCHAR*)&VALUE_BINDING(*pTableBinding, Rowset.m_pData);
|
|
bFound = FALSE;
|
|
if(CHECK(CompareID(&bFound, pwszTableName,
|
|
pwszTableName1, m_pIDBInitialize), S_OK) && bFound)
|
|
{
|
|
//Catalog Name
|
|
if(STATUS_BINDING(*pCatalogBinding, Rowset.m_pData)==DBSTATUS_S_OK)
|
|
*ppwszCatalogName = wcsDuplicate((WCHAR*)&VALUE_BINDING(*pCatalogBinding, Rowset.m_pData));
|
|
//Schema Name
|
|
if(STATUS_BINDING(*pSchemaBinding, Rowset.m_pData)==DBSTATUS_S_OK)
|
|
*ppwszSchemaName = wcsDuplicate((WCHAR*)&VALUE_BINDING(*pSchemaBinding, Rowset.m_pData));
|
|
}
|
|
}
|
|
|
|
Rowset.ReleaseRows(hRow);
|
|
hRow = DB_NULL_HROW;
|
|
}
|
|
|
|
//Error
|
|
if(!bFound)
|
|
{
|
|
TERROR("Unable to find the table \"" << pwszTableName << "\"in the Schema Rowset?");
|
|
QTESTC(bFound);
|
|
return FALSE;
|
|
}
|
|
CLEANUP:
|
|
if (DB_NULL_HROW != hRow)
|
|
Rowset.ReleaseRows(hRow);
|
|
SAFE_RELEASE(pIRowset);
|
|
return TRUE;
|
|
} //TCITableDefinition::GetCatalogSchemaNames
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Build a valid table name of a certain length
|
|
//--------------------------------------------------------------------------
|
|
WCHAR* TCITableDefinition::BuildValidName(size_t length, WCHAR* pattern)
|
|
{
|
|
WCHAR* pwszBuffer = NULL;
|
|
size_t cLen = wcslen(pattern), i;
|
|
|
|
SAFE_ALLOC(pwszBuffer, WCHAR, i=(length+1));
|
|
memset(pwszBuffer, 0, i);
|
|
for (i=0; i< length - cLen; i+=cLen)
|
|
wcscat(pwszBuffer, pattern);
|
|
// manage the rest of the characters
|
|
wcsncat(pwszBuffer, pattern, length-i);
|
|
CLEANUP:
|
|
return pwszBuffer;
|
|
} //TCITableDefinition::BuildValidName
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Build an invalid table name of a certain length
|
|
// the pattern is supposed to be shorter than the string to be build
|
|
//--------------------------------------------------------------------------
|
|
WCHAR* TCITableDefinition::BuildInvalidName(size_t length, WCHAR* pattern, WCHAR* invchars)
|
|
{
|
|
WCHAR* pwszBuffer=NULL;
|
|
size_t cLen = wcslen(pattern), i, cInvLen=wcslen(invchars);
|
|
|
|
pwszBuffer = (WCHAR*) PROVIDER_ALLOC( (length + 1) * sizeof(WCHAR) );
|
|
if (!pwszBuffer)
|
|
goto CLEANUP;
|
|
|
|
if (length > cInvLen+cLen)
|
|
{
|
|
wcscpy(pwszBuffer, pattern);
|
|
wcscat(pwszBuffer, invchars);
|
|
}
|
|
else
|
|
{
|
|
wcscpy(pwszBuffer, L"aa");
|
|
wcsncat(pwszBuffer, invchars, length-wcslen(pwszBuffer)-1);
|
|
pwszBuffer[length] = 0;
|
|
assert( wcslen(pwszBuffer) < length );
|
|
return pwszBuffer;
|
|
}
|
|
for (i=wcslen(pwszBuffer); i< length - cLen; i+=cLen)
|
|
wcscat(pwszBuffer, pattern);
|
|
// manage the rest of the characters
|
|
for (; i<length; i++)
|
|
wcscat(pwszBuffer, L"a");
|
|
|
|
CLEANUP:
|
|
return pwszBuffer;
|
|
} //TCITableDefinition::BuildInvalidName
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Uses m_pTable to get a column description for all types
|
|
//---------------------------------------------------------------------
|
|
void TCITableDefinition::GetProviderTypes(void)
|
|
{
|
|
CList <WCHAR*, WCHAR*> ListNativeTemp;
|
|
CList <DBTYPE, DBTYPE> ListDataTypes;
|
|
|
|
if (m_pTable)
|
|
delete m_pTable;
|
|
|
|
m_pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
// get the provider types list
|
|
// all types appear in CreateColList, so I don't have to use CreateTypeColInfo
|
|
m_pTable->CreateTypeColInfo(ListNativeTemp, ListDataTypes, ALLTYPES);
|
|
m_pTable->DuplicateColList(m_ColList);
|
|
// in m_rgColumnDesc I would rather load just the types prepared for table creation
|
|
m_pTable->CreateColInfo(ListNativeTemp, ListDataTypes, ALLTYPES);
|
|
// build the column description array
|
|
m_pTable->BuildColumnDescs(&m_rgColumnDesc);
|
|
m_cColumnDesc = m_pTable->CountColumnsOnTable();
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
ReleaseAllColumnPropSets(m_rgColumnDesc, m_cColumnDesc);
|
|
delete m_pTable;
|
|
m_pTable = NULL;
|
|
} //TCITableDefinition::GetProviderTypes
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Sets all the columns to maximum size as got from m_ColList
|
|
// (based on information read from PROVIDER_TYPES Rowset)
|
|
//
|
|
// RESULT:
|
|
// TRUE - set for every element in column desc array
|
|
// FALSE - could not be set for every element in thee array
|
|
//---------------------------------------------------------------------
|
|
BOOL TCITableDefinition::SetMaximumColSize
|
|
(
|
|
DBCOLUMNDESC *rgColumnDesc,
|
|
DBORDINAL cColumnDesc
|
|
)
|
|
{
|
|
POSITION pos;
|
|
CCol col;
|
|
DBORDINAL i;
|
|
WCHAR *pwszType;
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
pwszType = GetColumnTypeName(&rgColumnDesc[i]);
|
|
|
|
// look for the type which fits with column type
|
|
for ( pos=m_ColList.GetHeadPosition(), col=m_ColList.GetNext(pos);
|
|
wcscmp(col.GetProviderTypeName(), pwszType) && pos;
|
|
col=m_ColList.GetNext(pos));
|
|
if (wcscmp(col.GetProviderTypeName(), pwszType) )
|
|
continue;
|
|
// set to max column size
|
|
rgColumnDesc[i].ulColumnSize = col.GetColumnSize();
|
|
}
|
|
return TRUE;
|
|
} //TCITableDefinition::SetMaximumColSize
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Sets all the column sizes to 0
|
|
// RESULT:
|
|
// TRUE - set for every element in column desc array
|
|
// FALSE - could not be set for every element in thee array
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::SetZeroColSize
|
|
(
|
|
DBCOLUMNDESC *rgColumnDesc,
|
|
DBORDINAL cColumnDesc
|
|
)
|
|
{
|
|
DBORDINAL i;
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
// set column size to 0
|
|
rgColumnDesc[i].ulColumnSize = 0;
|
|
}
|
|
return TRUE;
|
|
} //TCITableDefinition::SetZeroColSize
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember CheckReturnedDBID about the columns in the table
|
|
// pIndexID - [IN] the DBID asked for
|
|
// ppIndexID - [IN] the DBID created
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::CheckReturnedDBID(
|
|
DBID *pIndexID, // passed to CreateIndex
|
|
DBID **ppIndexID // returned by CreateIndex
|
|
)
|
|
{
|
|
if (!pIndexID)
|
|
return *ppIndexID != NULL;
|
|
|
|
if (!ppIndexID)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (*ppIndexID == NULL)
|
|
return FALSE;
|
|
|
|
if (pIndexID->eKind != (*ppIndexID)->eKind)
|
|
return TRUE;
|
|
|
|
return CompareDBID(*pIndexID, **ppIndexID);
|
|
} //TCITableDefinition::CheckReturnedDBID
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember GetInfo about the columns in the table
|
|
// prgInfo - [OUT] the array of column information
|
|
// pcColumns - [OUT] the size of the array
|
|
// ppStringBuffer - [OUT] memory for info in the array
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::GetColumnInfo
|
|
(
|
|
DBID *pTableID,
|
|
DBORDINAL *pcColumns,
|
|
DBCOLUMNINFO **prgInfo,
|
|
OLECHAR **ppStringBuffer
|
|
)
|
|
{
|
|
IColumnsInfo *pIColumnsInfo;
|
|
|
|
if ( (m_hr = m_pIOpenRowset->OpenRowset(NULL, pTableID, NULL, IID_IColumnsInfo,
|
|
0, NULL, (IUnknown**)&pIColumnsInfo)) != S_OK)
|
|
{
|
|
*prgInfo = NULL;
|
|
*pcColumns = 0;
|
|
*ppStringBuffer = NULL;
|
|
return FALSE;
|
|
}
|
|
|
|
if (!CHECK(m_hr = pIColumnsInfo->GetColumnInfo(pcColumns, prgInfo, ppStringBuffer), S_OK))
|
|
return FALSE;
|
|
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
return TRUE;
|
|
} //TCITableDefinition::GetColumnInfo
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Get an array od Column Descriptors on a Table
|
|
//---------------------------------------------------------------------
|
|
BOOL TCITableDefinition::GetColumnDescOnTable(
|
|
DBID *pTableID,
|
|
DBCOLUMNDESC **prgColumnDesc,
|
|
DBORDINAL *cColumnDesc
|
|
)
|
|
{
|
|
if (!m_pTable)
|
|
return FALSE;
|
|
|
|
// get info in m_pTable->m_ColList
|
|
m_pTable->GetTableColumnInfo(pTableID);
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
pTableID || DBKIND_NAME != pTableID->eKind? pTableID->uName.pwszName: NULL);
|
|
m_pTable->ColList2ColumnDesc(prgColumnDesc, cColumnDesc);
|
|
return TRUE;
|
|
} //TCITableDefinition::GetColumnDescOnTable
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Passes a type name and retrieves the column from m_ColList with info about that type
|
|
//---------------------------------------------------------------------
|
|
CCol TCITableDefinition::GetType(WCHAR *pwszTypeName, DBTYPE wType, BOOL *fExists)
|
|
{
|
|
POSITION pos;
|
|
CCol col;
|
|
BOOL fRes = FALSE;
|
|
|
|
for (pos = m_ColList.GetHeadPosition(); pos && !fRes; )
|
|
{
|
|
col = m_ColList.GetNext(pos);
|
|
fRes = (0 == wcscmp(col.GetProviderTypeName(), pwszTypeName))
|
|
&& (wType == col.GetProviderType());
|
|
}
|
|
|
|
if (fExists)
|
|
*fExists = fRes;
|
|
|
|
return fRes? col : m_ColList.GetHead();
|
|
} //TCITableDefinition::GetType
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// @mfunc Check whether the array of ColumnDesc sent was preserved
|
|
// @rdesc TRUE or FALSE
|
|
// All the data should be inside, the only thing that is allowed to be modified <nl>
|
|
// is the property status
|
|
//------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::IsColumnDescPreserved
|
|
(
|
|
DBCOLUMNDESC *rgInColumnDesc, // the array passed to ITableDefinition::CreateTable
|
|
DBCOLUMNDESC *rgOutColumnDesc, // the aray returned by ITableDefinition::CreateTable
|
|
DBORDINAL cColumnDesc // the size of the arrays
|
|
)
|
|
{
|
|
// when this function is called, it is supposed that m_HasAuto... were set by GetTableColumnInfo
|
|
// and unmodified ever since
|
|
ULONG i, cPropSets, cProp;
|
|
DBPROPSET *pInPropSet, *pOutPropSet;
|
|
|
|
if (NULL == rgInColumnDesc || NULL == rgOutColumnDesc)
|
|
return (0 == cColumnDesc) || (rgOutColumnDesc == rgInColumnDesc);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
// compare everything in the stru
|
|
if (!CHECK(rgInColumnDesc[i].pTypeInfo == rgOutColumnDesc[i].pTypeInfo, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(rgInColumnDesc[i].ulColumnSize == rgOutColumnDesc[i].ulColumnSize, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(rgInColumnDesc[i].wType == rgOutColumnDesc[i].wType, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(rgInColumnDesc[i].bPrecision == rgOutColumnDesc[i].bPrecision, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(rgInColumnDesc[i].bScale == rgOutColumnDesc[i].bScale, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(rgInColumnDesc[i].pclsid == rgOutColumnDesc[i].pclsid, TRUE))
|
|
return FALSE;
|
|
if (INVALID_DBKIND != rgInColumnDesc[i].dbcid.eKind)
|
|
{
|
|
// CompareDBID with NULL DSO interface since the ids should
|
|
// match exactly
|
|
if (!CHECK(m_hr = CompareDBID(rgInColumnDesc[i].dbcid,
|
|
rgOutColumnDesc[i].dbcid, NULL), TRUE))
|
|
return FALSE;
|
|
}
|
|
else
|
|
if (INVALID_DBKIND != rgOutColumnDesc[i].dbcid.eKind)
|
|
return FALSE;
|
|
// compare the properties
|
|
if (!CHECK(rgInColumnDesc[i].cPropertySets == rgOutColumnDesc[i].cPropertySets, TRUE))
|
|
return FALSE;
|
|
if ( (NULL == rgInColumnDesc[i].rgPropertySets)
|
|
|| (NULL == rgOutColumnDesc[i].rgPropertySets))
|
|
if ( 0 != rgOutColumnDesc[i].cPropertySets
|
|
&& !COMPARE(rgInColumnDesc[i].rgPropertySets, rgOutColumnDesc[i].rgPropertySets))
|
|
return FALSE;
|
|
else
|
|
continue;
|
|
for (cPropSets=0; cPropSets<rgInColumnDesc[i].cPropertySets; cPropSets++)
|
|
{
|
|
// compare the props in that prop set
|
|
pInPropSet = &(rgInColumnDesc[i].rgPropertySets[cPropSets]);
|
|
pOutPropSet = &(rgOutColumnDesc[i].rgPropertySets[cPropSets]);
|
|
|
|
if (!CHECK(pInPropSet->guidPropertySet == pOutPropSet->guidPropertySet, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(pInPropSet->cProperties == pOutPropSet->cProperties, TRUE))
|
|
return FALSE;
|
|
if ( (NULL == pInPropSet->rgProperties)
|
|
|| (NULL == pOutPropSet->rgProperties))
|
|
if (0 != pOutPropSet->cProperties
|
|
&& !COMPARE(pInPropSet->rgProperties, pOutPropSet->rgProperties))
|
|
return FALSE;
|
|
else
|
|
continue;
|
|
|
|
// compare the properties
|
|
for (cProp=0; cProp<pInPropSet->cProperties; cProp++)
|
|
{
|
|
if (!CHECK(pInPropSet->rgProperties[cProp].dwPropertyID ==
|
|
pOutPropSet->rgProperties[cProp].dwPropertyID, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(pInPropSet->rgProperties[cProp].dwOptions ==
|
|
pOutPropSet->rgProperties[cProp].dwOptions, TRUE))
|
|
return FALSE;
|
|
// use NULL fr DSO interface
|
|
if (!CHECK(m_hr = CompareDBID(pInPropSet->rgProperties[cProp].colid,
|
|
pOutPropSet->rgProperties[cProp].colid,
|
|
NULL), TRUE))
|
|
return FALSE;
|
|
// protection against assertion errors in CompareVariant
|
|
if (
|
|
(rgInColumnDesc[i].wType != DBTYPE_GUID) &&
|
|
(rgInColumnDesc[i].wType != DBTYPE_BYTES) &&
|
|
(rgInColumnDesc[i].wType != DBTYPE_STR) &&
|
|
(rgInColumnDesc[i].wType != DBTYPE_WSTR) &&
|
|
(rgInColumnDesc[i].wType != DBTYPE_NUMERIC) &&
|
|
(rgInColumnDesc[i].wType != DBTYPE_DBTIMESTAMP)
|
|
)
|
|
if (!CHECK(CompareVariant(&pInPropSet->rgProperties[cProp].vValue,
|
|
&pOutPropSet->rgProperties[cProp].vValue), TRUE))
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
} //TCITableDefinition::IsColumnDescPreserved
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Set a property in the property sets of a DBCOLUMNDESC
|
|
//---------------------------------------------------------------------
|
|
BOOL TCITableDefinition::SetProperty
|
|
(
|
|
DBPROPSET **prgPropertySets, // [in/out] array of property sets
|
|
ULONG *pcPropertySets, // [in/out] number of property sets
|
|
DBPROPID propID, // [in] property ID
|
|
DBTYPE wType, // [in] value type
|
|
LPVOID value, // [in] property value
|
|
DBPROPOPTIONS dwOption/*=DPROPOPTIONS_OPTIONAL*/, // [in] prop options
|
|
DBID colid/*=DB_NULLID*/, // [in] col id
|
|
GUID guidPropertySet/*DBPROPSET_COLUMN*/,// [in] the GUID of the propset
|
|
ULONG *pcPropSet/*=NULL*/, // [out] index of property set
|
|
ULONG *pcProp/*=NULL*/ // [out] index in the rgProperties array
|
|
)
|
|
{
|
|
LONG i;
|
|
DBPROPSET *pPropSet;
|
|
BOOL fRes = FALSE, fFound;
|
|
ULONG cPropSet, cProp;
|
|
|
|
if (wType != DBTYPE_VARIANT)
|
|
{
|
|
TESTC(::SetProperty(propID, guidPropertySet, pcPropertySets, prgPropertySets, value,
|
|
wType, dwOption, colid));
|
|
}
|
|
else
|
|
{
|
|
TESTC(::SetProperty(propID, guidPropertySet, pcPropertySets, prgPropertySets, value,
|
|
VT_I2, dwOption, colid));
|
|
}
|
|
|
|
|
|
fRes = TRUE;
|
|
|
|
for (i=(int)(*pcPropertySets - 1), fFound = FALSE; i >= 0 && !fFound; i--)
|
|
{
|
|
fFound = (*prgPropertySets)[i].guidPropertySet == guidPropertySet;
|
|
cPropSet = (ULONG)i;
|
|
}
|
|
|
|
TESTC(fFound);
|
|
|
|
pPropSet = &((*prgPropertySets)[cPropSet]);
|
|
for (i=pPropSet->cProperties - 1, fFound = FALSE; i >= 0 && !fFound; i--)
|
|
{
|
|
if (TRUE == (fFound = pPropSet->rgProperties[i].dwPropertyID == propID))
|
|
{
|
|
cProp = (ULONG)i;
|
|
if (DBTYPE_VARIANT == wType)
|
|
{
|
|
pPropSet->rgProperties[i].vValue.vt = ((VARIANT*)value)->vt;
|
|
FillVariant(&pPropSet->rgProperties[i].vValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pcPropSet)
|
|
*pcPropSet = cPropSet;
|
|
|
|
if (pcProp)
|
|
*pcProp = cProp;
|
|
|
|
TESTC(fFound);
|
|
fRes = TRUE;
|
|
|
|
CLEANUP:
|
|
return fRes;
|
|
} //TCITableDefinition::SetProperty
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// @cmember Set a default property in the property sets of a DBCOLUMNDESC
|
|
//---------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::SetDefaultProperty(
|
|
DBPROPSET **prgPropertySets, // [in/out] array of property sets
|
|
ULONG *pcPropertySets, // [in/out] number of property sets
|
|
VARIANT *pvalue, // [in] property value
|
|
DBPROPOPTIONS dwOption /*= DBPROPOPTIONS_OPTIONAL*/, // [in] prop options
|
|
DBID colid /*= DB_NULLID*/, // [in] col id
|
|
GUID guidPropertySet /*= DBPROPSET_COLUMN*/, // [in] the GUID of the propset
|
|
ULONG *pcPropSet /*= NULL*/, // [out] index of property set
|
|
ULONG *pcProp /*=NULL*/ // [out] index in the rgProperties array
|
|
)
|
|
{
|
|
BOOL fRes = FALSE;
|
|
ULONG cPropSet;
|
|
ULONG cProp;
|
|
|
|
TESTC(NULL != pvalue);
|
|
TESTC(SetProperty(prgPropertySets, pcPropertySets, DBPROP_COL_DEFAULT,
|
|
DBTYPE_I2, 0, dwOption, colid, DBPROPSET_COLUMN, &cPropSet, &cProp));
|
|
|
|
VariantCopy(&((*prgPropertySets)[cPropSet].rgProperties[cProp].vValue), pvalue);
|
|
if (pcPropSet)
|
|
*pcPropSet = cPropSet;
|
|
if (pcProp)
|
|
*pcProp = cProp;
|
|
fRes = TRUE;
|
|
|
|
CLEANUP:
|
|
return fRes;
|
|
} // TCITableDefinition::SetDefaultProperty
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// TCITableDefinition::Insert
|
|
//
|
|
// CTable |
|
|
// Insert |
|
|
// Inserts 1 row in table using IRowsetNewRow. This function is called
|
|
// by the pulic Insert function.
|
|
//
|
|
// @mfunc Insert
|
|
// @rdesc HRESULT indicating success or failure
|
|
// @flag S_OK | Function ran without problem
|
|
// @flag E_FAIL | No Columns Marked for use or SetNewData failed
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::Insert(
|
|
DBCOUNTITEM ulRowNumber, // @parm [IN] Row number to insert (0 for next)
|
|
IUnknown *pIUnknown, // @parm [IN] Pointer to rowset interface
|
|
ULONG cNulls, // @parm [IN] Number of columns to be set to NULL (DEFAULT 0)
|
|
DBORDINAL *rgNulls, // @parm [IN] Array of columns to be set to NULL (DEFAULT NULL)
|
|
CTable *pTable // @parm [IN] Table (DEFAULT NULL - use m_pTable)
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
HACCESSOR hAccessor = NULL;
|
|
BYTE* pData = NULL;
|
|
DBCOUNTITEM cBindings = 0;
|
|
DBBINDING* rgBindings = NULL;
|
|
IDBProperties* pIDBProperties = NULL;
|
|
IGetDataSource* pIGetDataSource = NULL;
|
|
ULONG nBinding, nNull;
|
|
BOOL fFound;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
IAccessor *pIAccessor = NULL;
|
|
ULONG cRefCounts = ULONG_MAX;
|
|
|
|
if (!pTable)
|
|
pTable = m_pTable;
|
|
|
|
// Find row number to use on insert
|
|
if (ulRowNumber == 0)
|
|
ulRowNumber = pTable->GetNextRowNumber();
|
|
|
|
TESTC(NULL != pIUnknown);
|
|
TESTC(VerifyInterface(pIUnknown, IID_IAccessor, ROWSET_INTERFACE, (IUnknown**)&pIAccessor));
|
|
TESTC(VerifyInterface(pIUnknown, IID_IRowsetChange, ROWSET_INTERFACE, (IUnknown**)&pIRowsetChange));
|
|
|
|
//Get the DataSource
|
|
TESTC(VerifyInterface(m_pIOpenRowset, IID_IGetDataSource, SESSION_INTERFACE, (IUnknown**)&pIGetDataSource));
|
|
TESTC_(hr = pIGetDataSource->GetDataSource(IID_IDBProperties, (IUnknown**)&pIDBProperties), S_OK);
|
|
|
|
//Get an accessor with all the writeable columns
|
|
TESTC_(hr = GetAccessorAndBindings(pIRowsetChange,
|
|
DBACCESSOR_ROWDATA,
|
|
&hAccessor, &rgBindings, &cBindings, NULL,
|
|
DBPART_VALUE |DBPART_STATUS |DBPART_LENGTH,
|
|
UPDATEABLE_COLS_BOUND, FORWARD, NO_COLS_BY_REF, NULL,
|
|
NULL, NULL, DBTYPE_EMPTY, 0, NULL), S_OK);
|
|
|
|
// Fill buffer with appropriate data for insert of this row number
|
|
TESTC_(hr = FillInputBindings(
|
|
pTable,
|
|
DBACCESSOR_ROWDATA,
|
|
cBindings,
|
|
rgBindings,
|
|
&pData,
|
|
ulRowNumber,
|
|
0,
|
|
NULL),S_OK);
|
|
|
|
// set the NULL columns
|
|
for (nBinding = 0; nBinding < cBindings; nBinding++)
|
|
{
|
|
for (fFound = FALSE, nNull = 0; nNull < cNulls && !fFound; nNull++)
|
|
{
|
|
if (rgBindings[nBinding].iOrdinal == rgNulls[nNull])
|
|
{
|
|
*(DBSTATUS*)(pData+rgBindings[nBinding].obStatus) = DBSTATUS_S_ISNULL;
|
|
fFound = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// release previous accessor and create a new one
|
|
hr = pIRowsetChange->InsertRow(NULL, hAccessor, pData, NULL);
|
|
|
|
if (DB_E_ERRORSOCCURRED == hr)
|
|
{
|
|
SHORT *pMyData;
|
|
|
|
for (ULONG i=0; i<cBindings; i++)
|
|
{
|
|
pMyData = (SHORT*)(pData+rgBindings[i].obStatus);
|
|
if (DBSTATUS_S_OK != *pMyData && DBSTATUS_E_UNAVAILABLE != *pMyData)
|
|
odtLog << "bindings " << i << "\n";
|
|
}
|
|
|
|
}
|
|
// We have successfully inserted if we got this far
|
|
pTable->AddRow(); //increments pTable->m_ulNextRow
|
|
|
|
CLEANUP:
|
|
if(hAccessor && pIAccessor)
|
|
{
|
|
pIAccessor->ReleaseAccessor(hAccessor, &cRefCounts);
|
|
COMPARE(cRefCounts,0);
|
|
}
|
|
|
|
SAFE_RELEASE(pIAccessor);
|
|
FreeAccessorBindings(cBindings, rgBindings);
|
|
PROVIDER_FREE(pData);
|
|
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
SAFE_RELEASE(pIGetDataSource);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
return hr;
|
|
} //TCITableDefinition::Insert
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember StartTransaction method
|
|
// RETURN
|
|
// S_OK - an isolation level could be set and a transaction started
|
|
// E_FAIL - could not start a transaction
|
|
//--------------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::StartTransaction(ITransactionLocal *pITransactionLocal)
|
|
{
|
|
ULONG n, i;
|
|
HRESULT hr;
|
|
ISOLEVEL rgIsoLevel[] = {ISOLATIONLEVEL_BROWSE, ISOLATIONLEVEL_CURSORSTABILITY,
|
|
ISOLATIONLEVEL_ISOLATED, ISOLATIONLEVEL_CHAOS};
|
|
|
|
if (NULL == pITransactionLocal)
|
|
return E_FAIL;
|
|
|
|
n = NUMELEM(rgIsoLevel);
|
|
for (i=0; i<n; i++)
|
|
{
|
|
if (S_OK == (hr = pITransactionLocal->StartTransaction(rgIsoLevel[i], 0, NULL, NULL)))
|
|
{
|
|
return S_OK;
|
|
}
|
|
}
|
|
return E_FAIL;
|
|
} //TCITableDefinition::StartTransaction
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// TCITableDefinition::AddColumnAndCheck
|
|
//
|
|
// Add a column to the table and check the result
|
|
// RETURN value is the ret value of ITableDefinition::AddColumn
|
|
//---------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::AddColumnAndCheck(
|
|
DBID *pTableID, // [IN] table ID
|
|
DBCOLUMNDESC *pColumnDesc, // [IN] descriptor of the column to be added
|
|
DBID **ppColumnID, // [OUT] column ID for the resulted column
|
|
ITableDefinition *pITableDefinition,/*= NULL*/// [IN] pointer to ITableDefinition
|
|
DBID *pBaseTableID/*= NULL*/ // [IN] if provided, this is the table DBID that should be used
|
|
// in metadata comparison (e.g. pTableID might be the qualified name)
|
|
)
|
|
// sometimes there is not a unique expected result (e.g. one property could be supported or not)
|
|
// using Validate == FALSE you can protect the code from getting errors
|
|
{
|
|
DBCOLUMNDESC *rgOldCD = NULL;
|
|
DBORDINAL nOldlen = 0;
|
|
DBCOLUMNDESC *rgNewCD = NULL;
|
|
DBORDINAL nNewlen = 0;
|
|
DBCOLUMNDESC *pOriginalColumnDesc = NULL;
|
|
BOOL fRes = TRUE;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (!pBaseTableID)
|
|
pBaseTableID = pTableID;
|
|
|
|
pITableDefinition = (NULL == pITableDefinition) ? m_pITableDefinition: pITableDefinition;
|
|
TESTC(NULL != pITableDefinition);
|
|
|
|
GetColumnDescOnTable(pBaseTableID, &rgOldCD, &nOldlen);
|
|
if (ppColumnID)
|
|
*ppColumnID = NULL;
|
|
|
|
CHECK(NULL == pColumnDesc
|
|
|| NULL != DuplicateColumnDesc(pColumnDesc, 1, &pOriginalColumnDesc), TRUE);
|
|
|
|
// here use pTableID, everywhere else use pBaseTableID
|
|
hr = pITableDefinition->AddColumn(pTableID, pColumnDesc, ppColumnID);
|
|
|
|
if ( pOriginalColumnDesc
|
|
&& !COMPARE(IsColumnDescPreserved(pOriginalColumnDesc, pColumnDesc, 1), TRUE))
|
|
{
|
|
odtLog << "\tERROR: column desc is not preserved\n";
|
|
}
|
|
|
|
// check the status of the column properties
|
|
COMPARE(CheckColPropStatus(1, pColumnDesc, hr), TRUE);
|
|
|
|
if (FAILED(hr) && ppColumnID)
|
|
COMPARE(NULL == *ppColumnID, TRUE);
|
|
|
|
// get the new stru of the table
|
|
GetColumnDescOnTable(pBaseTableID, &rgNewCD, &nNewlen);
|
|
|
|
// check the result of the operation
|
|
if (SUCCEEDED(hr))
|
|
// get info about the columns in the altered table and compare them, one by one!
|
|
COMPARE(CheckColInfo(rgOldCD, nOldlen, rgNewCD, nNewlen, pColumnDesc), TRUE);
|
|
else
|
|
// make sure that the table stru remained the same
|
|
COMPARE(AreColEqual(rgOldCD, nOldlen, rgNewCD, nNewlen), TRUE);
|
|
|
|
CLEANUP:
|
|
// save old values into the new ones and release the others
|
|
ReleaseColumnDesc(rgOldCD, nOldlen);
|
|
ReleaseColumnDesc(rgNewCD, nNewlen);
|
|
ReleaseColumnDesc(pOriginalColumnDesc, 1);
|
|
return hr;
|
|
} //TCITableDefinition::AddColumnAndCheck
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @member Create the table using ITableDefinition::CreateTable and
|
|
// check its creation
|
|
//---------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::CreateAndCheckTable(
|
|
ITableDefinition *pITableDefinition, // [in] pointer to the ITableDefinition interface to be used
|
|
IUnknown *pUnkOuter, // [in] pointer to controlling unknown
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBORDINAL cColumnDescs, // [in] the number of columns to be created
|
|
DBCOLUMNDESC *rgColumnDescs, // [in/out] array of columns to be created
|
|
REFIID riid, // [in] rowset interface to be returned
|
|
ULONG cPropertySets, // [in] number of roset property sets asked
|
|
DBPROPSET *rgPropertySets, // [in/out] array of rowset property sets
|
|
DBID **ppTableID, // [out] returned table ID
|
|
IUnknown **ppRowset // [out] pointer to outer interface
|
|
)
|
|
{
|
|
BOOL fExists;
|
|
DBORDINAL cOriginalColumnDescs = 0;
|
|
DBCOLUMNDESC *rgOriginalColumnDescs = NULL;
|
|
ULONG cOriginalPropertySets = 0;
|
|
DBPROPSET *rgOriginalPropertySets = NULL;
|
|
HRESULT hres;
|
|
DBID *pNewTableID = NULL;
|
|
CTable *pTable = new CTable(pITableDefinition, (LPWSTR)gwszModuleName);
|
|
IUnknown *pIUnknown = NULL; // used to pass the rowset pointer to AreColumnsCreatedOK
|
|
|
|
ASSERT(pTable);
|
|
ASSERT(pITableDefinition);
|
|
|
|
// save the original values
|
|
CHECK(0 == cColumnDescs || NULL == rgColumnDescs
|
|
|| NULL != DuplicateColumnDesc(rgColumnDescs, cColumnDescs, &rgOriginalColumnDescs), TRUE);
|
|
cOriginalColumnDescs = cColumnDescs;
|
|
CHECK(0 == cPropertySets || NULL == rgPropertySets
|
|
|| DuplicatePropertySets(cPropertySets, rgPropertySets, &cOriginalPropertySets, &rgOriginalPropertySets), TRUE);
|
|
|
|
// go for ITableDefinition::CreateTable
|
|
hres = pITableDefinition->CreateTable(pUnkOuter, pTableID, cColumnDescs, rgColumnDescs, riid,
|
|
cPropertySets, rgPropertySets, ppTableID, ppRowset);
|
|
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
COMPARE(NULL == ppTableID || NULL != *ppTableID, TRUE);
|
|
}
|
|
else
|
|
{
|
|
COMPARE(NULL == ppTableID || NULL == *ppTableID, TRUE);
|
|
}
|
|
|
|
if (rgOriginalColumnDescs
|
|
&& !COMPARE(IsColumnDescPreserved(rgOriginalColumnDescs, rgColumnDescs, cColumnDescs), TRUE))
|
|
{
|
|
odtLog << "\tERROR: array of column desc is not preserved\n";
|
|
}
|
|
|
|
if ( rgOriginalPropertySets
|
|
&& !COMPARE(IsRowsetPropSetPreserved(rgOriginalPropertySets, rgPropertySets, cPropertySets), TRUE))
|
|
{
|
|
odtLog << "\tERROR: the rowset property sets are not preserved\n";
|
|
}
|
|
|
|
COMPARE(CheckRwstTblPropStatus(cPropertySets, rgPropertySets, hres), TRUE);
|
|
COMPARE(CheckColPropStatus(cColumnDescs, rgColumnDescs, hres), TRUE);
|
|
|
|
pNewTableID = (ppTableID)? (*ppTableID): pTableID;
|
|
|
|
// if the table creation was reported as succeding, the table should exist
|
|
if ( SUCCEEDED(hres)
|
|
&& (!CHECK(pTable->DoesTableExist(pNewTableID, &fExists), S_OK) || !fExists))
|
|
{
|
|
if (!fExists)
|
|
odtLog << "\tERROR: despite the return value reported, the table doesn't exist\n";
|
|
}
|
|
|
|
// if the table creation was reported as failed, the table should not exist
|
|
if ( FAILED(hres)
|
|
&& DB_E_DUPLICATETABLEID != hres
|
|
&& DB_E_NOTABLE != hres
|
|
&& pNewTableID
|
|
&& (!CHECK(pTable->DoesTableExist(pNewTableID, &fExists), S_OK) || fExists))
|
|
{
|
|
if (!fExists)
|
|
odtLog << "\tERROR: despite the return value reported, the table exists\n";
|
|
}
|
|
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
pIUnknown = (ppRowset) ? (IUnknown*)(*ppRowset) : NULL;
|
|
COMPARE(AreColumnsCreatedOK(rgColumnDescs, cColumnDescs, pNewTableID, pIUnknown), TRUE);
|
|
|
|
if (ppRowset)
|
|
{
|
|
COMPARE(IsRowsetPropSetCreatedOK(rgPropertySets, cPropertySets, *ppRowset), TRUE);
|
|
COMPARE(!ppRowset || CheckRowset(*ppRowset), TRUE);
|
|
}
|
|
COMPARE(CheckReturnedDBID(pTableID, ppTableID), TRUE);
|
|
}
|
|
else
|
|
{
|
|
COMPARE(ppRowset && NULL == *ppRowset, TRUE);
|
|
COMPARE(!ppTableID || NULL == *ppTableID, TRUE);
|
|
}
|
|
|
|
delete pTable;
|
|
ReleaseColumnDesc(rgOriginalColumnDescs, cOriginalColumnDescs);
|
|
FreeProperties( &cOriginalPropertySets, &rgOriginalPropertySets);
|
|
return hres;
|
|
} //TCITableDefinition::CreateAndCheckTable
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @member Create the table using ITableDefinitionWithConstraints::CreateTableWithConstraints and
|
|
// check its creation
|
|
//---------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::CreateAndCheckTableWithConstraints(
|
|
ITableDefinitionWithConstraints *pITableDefinitionWithConstraints, // [in] pointer to the ITableDefinitionWithConstraints interface to be used
|
|
IUnknown *pUnkOuter, // [in] pointer to controlling unknown
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBORDINAL cColumnDescs, // [in] the number of columns to be created
|
|
DBCOLUMNDESC *rgColumnDescs, // [in/out] array of columns to be created
|
|
ULONG cConstraintDescs, // [in] the number of constraints to be created
|
|
DBCONSTRAINTDESC *rgConstraintDescs, // [in/out] array of constraints
|
|
REFIID riid, // [in] rowset interface to be returned
|
|
ULONG cPropertySets, // [in] number of roset property sets asked
|
|
DBPROPSET *rgPropertySets, // [in/out] array of rowset property sets
|
|
DBID **ppTableID, // [out] returned table ID
|
|
IUnknown **ppRowset // [out] pointer to outer interface
|
|
)
|
|
{
|
|
BOOL fExists;
|
|
DBORDINAL cOriginalColumnDescs = 0;
|
|
DBCOLUMNDESC *rgOriginalColumnDescs = NULL;
|
|
ULONG cOriginalPropertySets = 0;
|
|
DBPROPSET *rgOriginalPropertySets = NULL;
|
|
HRESULT hres;
|
|
DBID *pNewTableID = NULL;
|
|
CTable *pTable = new CTable(pITableDefinitionWithConstraints, (LPWSTR)gwszModuleName);
|
|
IUnknown *pIUnknown = NULL; // used to pass the rowset pointer to AreColumnsCreatedOK
|
|
CConstraints Constraints(pITableDefinitionWithConstraints);
|
|
DBORDINAL index;
|
|
|
|
ASSERT(pTable);
|
|
ASSERT(pITableDefinitionWithConstraints);
|
|
|
|
// save the original values
|
|
CHECK(0 == cColumnDescs || NULL == rgColumnDescs
|
|
|| NULL != DuplicateColumnDesc(rgColumnDescs, cColumnDescs, &rgOriginalColumnDescs), TRUE);
|
|
cOriginalColumnDescs = cColumnDescs;
|
|
CHECK(0 == cPropertySets || NULL == rgPropertySets
|
|
|| DuplicatePropertySets(cPropertySets, rgPropertySets, &cOriginalPropertySets, &rgOriginalPropertySets), TRUE);
|
|
|
|
// get original constraint set
|
|
if (pTableID && (DBKIND_NAME == pTableID->eKind) && pTableID->uName.pwszName)
|
|
{
|
|
CHECK(Constraints.GetConstraints(NULL, NULL, pTableID->uName.pwszName, NULL, NULL, NULL), S_OK);
|
|
}
|
|
|
|
// go for ITableDefinition::CreateTable
|
|
hres = pITableDefinitionWithConstraints->CreateTableWithConstraints(pUnkOuter,
|
|
pTableID, cColumnDescs, rgColumnDescs, cConstraintDescs, rgConstraintDescs,
|
|
riid, cPropertySets, rgPropertySets, ppTableID, ppRowset);
|
|
|
|
if ( rgOriginalColumnDescs
|
|
&& !COMPARE(IsColumnDescPreserved(rgOriginalColumnDescs, rgColumnDescs, cColumnDescs), TRUE))
|
|
{
|
|
odtLog << "\tERROR: array of column desc is not preserved\n";
|
|
}
|
|
|
|
if ( rgOriginalPropertySets
|
|
&& !COMPARE(IsRowsetPropSetPreserved(rgOriginalPropertySets, rgPropertySets, cPropertySets), TRUE))
|
|
{
|
|
odtLog << "\tERROR: the rowset property sets are not preserved\n";
|
|
}
|
|
|
|
COMPARE(CheckRwstTblPropStatus(cPropertySets, rgPropertySets, hres), TRUE);
|
|
COMPARE(CheckColPropStatus(cColumnDescs, rgColumnDescs, hres), TRUE);
|
|
|
|
pNewTableID = (ppTableID)? (*ppTableID): pTableID;
|
|
|
|
// if the table creation was reported as succeding, the table should exist
|
|
if ( SUCCEEDED(hres)
|
|
&& (!CHECK(pTable->DoesTableExist(pNewTableID, &fExists), S_OK) || !fExists))
|
|
{
|
|
if (!fExists)
|
|
odtLog << "\tERROR: despite the return value reported, the table doesn't exist\n";
|
|
}
|
|
|
|
// if the table creation was reported as failed, the table should not exist
|
|
if ( FAILED(hres)
|
|
&& DB_E_DUPLICATETABLEID != hres
|
|
&& DB_E_NOTABLE != hres
|
|
&& pNewTableID
|
|
&& (!CHECK(pTable->DoesTableExist(pNewTableID, &fExists), S_OK) || fExists))
|
|
{
|
|
if (!fExists)
|
|
odtLog << "\tERROR: despite the return value reported, the table exists\n";
|
|
}
|
|
|
|
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
pIUnknown = (ppRowset) ? (IUnknown*)(*ppRowset) : NULL;
|
|
COMPARE(AreColumnsCreatedOK(rgColumnDescs, cColumnDescs, pNewTableID, pIUnknown), TRUE);
|
|
if (ppRowset)
|
|
{
|
|
COMPARE(IsRowsetPropSetCreatedOK(rgPropertySets, cPropertySets, *ppRowset), TRUE);
|
|
COMPARE(!ppRowset || CheckRowset(*ppRowset), TRUE);
|
|
}
|
|
COMPARE(CheckReturnedDBID(pTableID, ppTableID), TRUE);
|
|
|
|
// check constraint creation
|
|
if (pNewTableID && (DBKIND_NAME == pNewTableID->eKind) && pNewTableID->uName.pwszName)
|
|
{
|
|
CHECK(Constraints.GetConstraints(NULL, NULL, pNewTableID->uName.pwszName, NULL, NULL, NULL), S_OK);
|
|
// the number of constraints created is greater than or equal to cConstraintDescs
|
|
// this happens because the user can ask for some more constraints using column props
|
|
COMPARE(Constraints.GetConstrNo() >= cConstraintDescs, TRUE);
|
|
|
|
for (index = 0; index < cConstraintDescs; index++)
|
|
{
|
|
// BEWARE: if deferred flag was set without deferrable
|
|
// flag being set, constraint should be immediate
|
|
if (rgConstraintDescs[index].Deferrability == DBDEFERRABILITY_DEFERRABLE)
|
|
rgConstraintDescs[index].Deferrability = 0;
|
|
}
|
|
|
|
CHECK(Constraints.CheckIncludedConstraints(cConstraintDescs, rgConstraintDescs), S_OK);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
COMPARE(NULL == ppRowset || NULL == *ppRowset, TRUE);
|
|
COMPARE(NULL == ppTableID || NULL == *ppTableID, TRUE);
|
|
|
|
// check no constraints existed on the table
|
|
if (DB_E_DUPLICATETABLEID == hres)
|
|
{
|
|
CHECK(Constraints.AreConstraintsPreserved(), S_OK);
|
|
}
|
|
else
|
|
{
|
|
// make sure no constraints exist for this table name (if not invalid)
|
|
if (pTableID && (DBKIND_NAME == pTableID->eKind) && pTableID->uName.pwszName)
|
|
{
|
|
CHECK(Constraints.GetConstraints(NULL, NULL, pTableID->uName.pwszName, NULL, NULL, NULL), S_OK);
|
|
COMPARE(Constraints.GetConstrNo(), 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
delete pTable;
|
|
|
|
ReleaseColumnDesc(rgOriginalColumnDescs, cOriginalColumnDescs);
|
|
FreeProperties( &cOriginalPropertySets, &rgOriginalPropertySets);
|
|
return hres;
|
|
} //TCITableDefinition::CreateAndCheckTableWithConstraints
|
|
|
|
|
|
|
|
|
|
// Add a constraint to a table using ITableDefinitionWithConstraints::AddConstraint and check its creation
|
|
HRESULT TCITableDefinition::AddConstraintAndCheck(
|
|
ITableDefinitionWithConstraints *pITableDefinitionWithConstraints, // [in] pointer to the ITableDefinitionWithConstraints interface to be used
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBCONSTRAINTDESC *pConstraintDesc, // [in] new constraint
|
|
BOOL fDifferentColTypesInFK
|
|
)
|
|
{
|
|
// this method assumes that the table indicated by pTableID does exist
|
|
HRESULT hr = E_FAIL;
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_DUPLICATECONSTRAINTID,
|
|
DB_E_BADCONSTRAINTID,
|
|
DB_E_BADCONSTRAINTTYPE,
|
|
DB_E_BADUPDATEDELETERULE,
|
|
DB_E_BADMATCHTYPE,
|
|
DB_E_BADDEFERRABILITY,
|
|
DB_E_BADCONSTRAINTFORM,
|
|
DB_E_NOCOLUMN,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(pITableDefinitionWithConstraints);
|
|
DBID *pConstraintID;
|
|
ULONG index;
|
|
|
|
// keep trace of whether the constraint DBID was NULL
|
|
pConstraintID = pConstraintDesc? pConstraintDesc->pConstraintID: NULL;
|
|
|
|
TESTC(NULL != pITableDefinitionWithConstraints);
|
|
|
|
// get all the constraints associated with the table
|
|
if (pTableID && DBKIND_NAME == pTableID->eKind)
|
|
{
|
|
TESTC_(Constraints.GetConstraints(NULL, NULL, pTableID->uName.pwszName, NULL, NULL, NULL), S_OK);
|
|
}
|
|
else
|
|
{
|
|
TESTC_(Constraints.GetConstraints(NULL, NULL, NULL, NULL, NULL, NULL), S_OK);
|
|
}
|
|
|
|
hr = pITableDefinitionWithConstraints->AddConstraint(pTableID, pConstraintDesc);
|
|
|
|
// check that constraint ID is not modified if set to NULL
|
|
COMPARE(!pConstraintDesc || (pConstraintID == pConstraintDesc->pConstraintID), TRUE);
|
|
|
|
// check that the result is one of the expected results
|
|
TESTC(CheckResult(hr, cValidHRes, rgValidHRes));
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
CHECK(Constraints.AreConstraintsPreserved(), S_OK);
|
|
}
|
|
else
|
|
{
|
|
TESTC(NULL != pTableID);
|
|
// check that the constraint was added
|
|
DBDEFERRABILITY def = pConstraintDesc->Deferrability;
|
|
// BEWARE: if deferred flag was set without deferrable
|
|
// flag being set, constraint should be immediate
|
|
if (pConstraintDesc->Deferrability == DBDEFERRABILITY_DEFERRABLE)
|
|
pConstraintDesc->Deferrability = 0;
|
|
CHECK(Constraints.CheckAddConstraints(1, pConstraintDesc), S_OK);
|
|
pConstraintDesc->Deferrability = def;
|
|
}
|
|
|
|
switch (hr)
|
|
{
|
|
case S_OK:
|
|
break;
|
|
|
|
case E_INVALIDARG:
|
|
// check the returned value condition (assume only one of them was set, if any)
|
|
TESTC( NULL == pTableID || NULL == pConstraintDesc
|
|
|| 0 < pConstraintDesc->cForeignKeyColumns && NULL == pConstraintDesc->rgForeignKeyColumnList
|
|
|| 0 < pConstraintDesc->cForeignKeyColumns && pConstraintDesc->cColumns != pConstraintDesc->cForeignKeyColumns
|
|
|| 0 < pConstraintDesc->cColumns && NULL == pConstraintDesc->rgColumnList
|
|
|| 0 != pConstraintDesc->cReserved && NULL == pConstraintDesc->rgReserved);
|
|
break;
|
|
|
|
case DB_E_BADCONSTRAINTID:
|
|
// conditions for DB_E_BADCONSTRAINTID
|
|
break;
|
|
|
|
case DB_E_DUPLICATECONSTRAINTID:
|
|
// condition for DB_E_DUPLICATECONSTRAINTID
|
|
if ( (NULL == Constraints[pConstraintDesc->pConstraintID])
|
|
&& (pTableID && DBKIND_NAME == pTableID->eKind))
|
|
{
|
|
DBCONSTRAINTDESC *pConstraintDesc = Constraints.GetConstraints();
|
|
|
|
// or there is a primary constraint on this table
|
|
for (index = 0; index < Constraints.GetConstrNo(); index++)
|
|
{
|
|
if (DBCONSTRAINTTYPE_PRIMARYKEY == pConstraintDesc->ConstraintType)
|
|
break;
|
|
}
|
|
TESTC(index < Constraints.GetConstrNo());
|
|
}
|
|
break;
|
|
|
|
case DB_E_BADCONSTRAINTTYPE:
|
|
// condition for DB_E_BADCONSTRAINTTYPE: ConstraintType was invalid or not supported by the provider
|
|
TESTC(DBCONSTRAINTTYPE_UNIQUE != pConstraintDesc->ConstraintType);
|
|
TESTC(DBCONSTRAINTTYPE_PRIMARYKEY != pConstraintDesc->ConstraintType);
|
|
|
|
TESTC(DBCONSTRAINTTYPE_FOREIGNKEY != pConstraintDesc->ConstraintType);
|
|
|
|
TESTC(DBCONSTRAINTTYPE_CHECK != pConstraintDesc->ConstraintType);
|
|
break;
|
|
|
|
case DB_E_BADUPDATEDELETERULE:
|
|
TESTC(DBCONSTRAINTTYPE_FOREIGNKEY == pConstraintDesc->ConstraintType);
|
|
break;
|
|
|
|
case DB_E_BADMATCHTYPE:
|
|
break;
|
|
|
|
case DB_E_BADDEFERRABILITY:
|
|
break;
|
|
|
|
case DB_E_BADCONSTRAINTFORM:
|
|
if (!( DBCONSTRAINTTYPE_FOREIGNKEY != pConstraintDesc->ConstraintType
|
|
&& (0 < pConstraintDesc->cForeignKeyColumns || NULL != pConstraintDesc->pReferencedTableID)
|
|
|| DBCONSTRAINTTYPE_CHECK == pConstraintDesc->ConstraintType && NULL == pConstraintDesc->pwszConstraintText
|
|
|| DBCONSTRAINTTYPE_CHECK == pConstraintDesc->ConstraintType && 0 != pConstraintDesc->cColumns
|
|
|| DBCONSTRAINTTYPE_CHECK != pConstraintDesc->ConstraintType && NULL != pConstraintDesc->pwszConstraintText
|
|
|| DBCONSTRAINTTYPE_FOREIGNKEY == pConstraintDesc->ConstraintType && 0 == pConstraintDesc->cForeignKeyColumns
|
|
|| ( DBCONSTRAINTTYPE_FOREIGNKEY == pConstraintDesc->ConstraintType
|
|
|| DBCONSTRAINTTYPE_PRIMARYKEY == pConstraintDesc->ConstraintType
|
|
|| DBCONSTRAINTTYPE_UNIQUE == pConstraintDesc->ConstraintType) && 0 == pConstraintDesc->cColumns
|
|
|| DBCONSTRAINTTYPE_FOREIGNKEY == pConstraintDesc->ConstraintType && NULL == pConstraintDesc->pReferencedTableID
|
|
))
|
|
{
|
|
// the only good alternative is that the columns in the referenced table and
|
|
// and the ones in the base table have different types
|
|
TESTC(fDifferentColTypesInFK);
|
|
}
|
|
// Note: the case when the column types of corresponding cols do not match in a FK is missing!
|
|
break;
|
|
|
|
case DB_E_NOCOLUMN:
|
|
// check that one of the columns referred does not exist in the table
|
|
// (either col in the base table or col in the referenced table for FK)
|
|
break;
|
|
|
|
case DB_E_NOTABLE:
|
|
// pReferencedTableID (for foreign keys) or pTableID does not exist
|
|
break;
|
|
|
|
case DB_E_TABLEINUSE:
|
|
case DB_SEC_E_PERMISSIONDENIED:
|
|
case DB_E_SCHEMAVIOLATION:
|
|
case XACT_E_XTIONEXISTS:
|
|
break;
|
|
|
|
case E_FAIL:
|
|
// this code is legal; caller should catch it if there
|
|
// is a more meaningful return value
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
};
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //TCITableDefinition::AddConstraintAndCheck
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// Drop a constraint to a table using ITableDefinitionWithConstraints::DropConstraint and check its deletion
|
|
HRESULT TCITableDefinition::DropConstraintAndCheck(
|
|
ITableDefinitionWithConstraints *pITableDefinitionWithConstraints, // [in] pointer to the ITableDefinitionWithConstraints interface to be used
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBID *pConstraintID // [in] pointer to the DBID of the constraint
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_NOCONSTRAINT,
|
|
DB_E_BADTABLEID,
|
|
DB_E_DROPRESTRICTED,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
DBORDINAL ulInitConstraints = 0;
|
|
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(pITableDefinitionWithConstraints);
|
|
|
|
TESTC(NULL != pITableDefinitionWithConstraints);
|
|
|
|
// get all the constraints associated with the table
|
|
if (pTableID && DBKIND_NAME == pTableID->eKind)
|
|
{
|
|
CHECK(Constraints.GetConstraints(NULL, NULL, pTableID->uName.pwszName, NULL, NULL, NULL), S_OK);
|
|
ulInitConstraints = Constraints.GetConstrNo();
|
|
}
|
|
else
|
|
{
|
|
CHECK(Constraints.GetConstraints(NULL, NULL, NULL, NULL, NULL, NULL), S_OK);
|
|
}
|
|
|
|
// drop the constraint
|
|
hr = pITableDefinitionWithConstraints->DropConstraint(pTableID, pConstraintID);
|
|
|
|
|
|
// check that the result is one of the expected results
|
|
COMPARE(CheckResult(hr, cValidHRes, rgValidHRes), TRUE);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
CHECK(Constraints.AreConstraintsPreserved(), S_OK);
|
|
}
|
|
else
|
|
{
|
|
// check that the constraint was dropped
|
|
if (NULL != pTableID && DBKIND_NAME == pTableID->eKind)
|
|
{
|
|
CConstraints NewConstraints(pITableDefinitionWithConstraints);
|
|
|
|
CHECK(NewConstraints.GetConstraints(NULL, NULL, pTableID->uName.pwszName, NULL, NULL, NULL), S_OK);
|
|
COMPARE(NULL == NewConstraints[pConstraintID], TRUE);
|
|
COMPARE(ulInitConstraints-1, NewConstraints.GetConstrNo());
|
|
CHECK(Constraints.CheckIncludedConstraints(NewConstraints.GetConstrNo(),
|
|
NewConstraints.GetConstraints()), S_OK);
|
|
}
|
|
|
|
}
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //TCITableDefinition::DropConstraintAndCheck
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @member Create the table using ITableDefinition::CreateTable,
|
|
// check its creation then drops the table and releases the rowset interface
|
|
//---------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::CCNDropTable(
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBORDINAL cColumnDescs, // [in] the number of columns to be created
|
|
DBCOLUMNDESC *rgColumnDescs, // [in/out] array of columns to be created
|
|
REFIID riid, // [in] rowset interface to be returned
|
|
ULONG cPropertySets, // [in] number of roset property sets asked
|
|
DBPROPSET *rgPropertySets, // [in/out] array of rowset property sets
|
|
BOOL fNullPPTableID/*=FALSE*/ // [in] if TRUE ppTableID will be NULL
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fExists;
|
|
DBID *pNewTableID = NULL;
|
|
DBID *pOutTableID = NULL; // [out] returned table ID
|
|
DBID **ppTableID = fNullPPTableID? NULL: &pOutTableID;
|
|
IUnknown *pRowset = NULL; // [out] pointer to outer interface
|
|
CTable *pTable = new CTable(m_pITableDefinition, (LPWSTR)gwszModuleName);
|
|
|
|
hr = CreateAndCheckTable(m_pITableDefinition, NULL, pTableID, cColumnDescs, rgColumnDescs, riid,
|
|
cPropertySets, rgPropertySets, ppTableID, &pRowset);
|
|
|
|
SAFE_RELEASE(pRowset);
|
|
|
|
pNewTableID = (ppTableID)? *ppTableID: pTableID;
|
|
if ( pNewTableID
|
|
&& DB_E_NOTABLE != hr
|
|
&& DB_E_DUPLICATETABLEID != hr
|
|
&& CHECK(pTable->DoesTableExist(pNewTableID, &fExists), S_OK)
|
|
&& fExists)
|
|
CHECK(m_pITableDefinition->DropTable(pNewTableID), S_OK);
|
|
|
|
delete pTable;
|
|
ReleaseDBID(pOutTableID);
|
|
return hr;
|
|
} //TCITableDefinition::CCNDropTable
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Check whether the columns were properly created
|
|
// The columns of the m_pTable are checked against the column descriptor array <nl>
|
|
// returned by ITableDefinition::CreateTable method.
|
|
// RETURNS
|
|
// TRUE - everything is created ok
|
|
// FALSE - errors
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::AreColumnsCreatedOK(
|
|
DBCOLUMNDESC *rgOutColumnDesc, // [in] the aray returned by ITableDefinition::CreateTable
|
|
DBORDINAL cColumnDesc, // [in] the size of the arrays
|
|
DBID *pTableID/*=NULL*/, // [in] Table ID
|
|
IUnknown *pIUnknown/*=NULL*/ // [in] pointer to a rowset interface on the table
|
|
)
|
|
{
|
|
DBORDINAL cCDFromTable;
|
|
BOOL fTestRes = TRUE;
|
|
DBCOLUMNDESC *rgCDFromTable = NULL;
|
|
ULONG i;
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
|
|
// get the descriptions of the columns in the table with DBID == m_pTable->GetTableID()
|
|
// the list of columns are stored in m_pTable->m_colList
|
|
GetColumnDescOnTable(pTableID? pTableID: &m_pTable->GetTableID(),
|
|
&rgCDFromTable, &cCDFromTable);
|
|
|
|
if (cColumnDesc != cCDFromTable)
|
|
{
|
|
odtLog << "the number of columns asked and created does not fit";
|
|
fTestRes = FALSE;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
fTestRes = fTestRes && CompareColumnDesc(&rgOutColumnDesc[i], &rgCDFromTable[i]);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgCDFromTable, cCDFromTable);
|
|
delete pTable;
|
|
return fTestRes;
|
|
} //TCITableDefinition::AreColumnsCreatedOK
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
//
|
|
// @member Check properties on rowseet and table
|
|
// returns TRUE if the prop set is set correctly
|
|
// FALSE otherwise
|
|
//--------------------------------------------------------------------
|
|
BOOL TCITableDefinition::CheckRwstTblPropStatus(
|
|
ULONG cPropSets, // [in] the size of the propset array
|
|
DBPROPSET *rgPropSets, // [in] propset array
|
|
HRESULT hr // [in] the result of the previous op
|
|
)
|
|
{
|
|
GUID guidExpectedPS;
|
|
ULONG cPropSet;
|
|
ULONG cProp;
|
|
BOOL fRes = TRUE;
|
|
|
|
if (!rgPropSets)
|
|
return TRUE;
|
|
|
|
for (cPropSet = 0; cPropSet < cPropSets; cPropSet++)
|
|
{
|
|
if (!rgPropSets[cPropSet].rgProperties)
|
|
continue;
|
|
guidExpectedPS = rgPropSets[cPropSet].guidPropertySet == DBPROPSET_ROWSET? DBPROPSET_ROWSET: DBPROPSET_TABLE;
|
|
for (cProp = 0; cProp < rgPropSets[cPropSet].cProperties; cProp++)
|
|
{
|
|
fRes = fRes && CheckPropertyStatus(rgPropSets[cPropSet].guidPropertySet, guidExpectedPS,
|
|
&rgPropSets[cPropSet].rgProperties[cProp], hr);
|
|
}
|
|
}
|
|
return fRes;
|
|
} //TCITableDefinition::CheckRwstTblPropStatus
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Check whether the property sets asked for rowset was preserved
|
|
// all the data should be inside, the only thing that is allowed to be modified <nl>
|
|
// is the property status
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::IsRowsetPropSetPreserved
|
|
(
|
|
DBPROPSET *rgInPropertySets, // the array passed to ITableDefinition::CreateTable
|
|
DBPROPSET *rgOutPropertySets, // the aray returned by ITableDefinition::CreateTable
|
|
ULONG cPropertySets // the size of the arrays
|
|
)
|
|
{
|
|
ULONG ps, pc;
|
|
|
|
if (NULL == rgInPropertySets)
|
|
return TRUE;
|
|
for (ps=0; ps<cPropertySets; ps++)
|
|
{
|
|
// compare the props in that prop set
|
|
if (!CHECK(rgInPropertySets[ps].guidPropertySet == rgOutPropertySets[ps].guidPropertySet, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(rgInPropertySets[ps].cProperties == rgOutPropertySets[ps].cProperties, TRUE))
|
|
return FALSE;
|
|
if (NULL == rgInPropertySets[ps].rgProperties)
|
|
continue;
|
|
|
|
for (pc=0; pc<rgInPropertySets[ps].cProperties; pc++)
|
|
{
|
|
if (!CHECK(rgInPropertySets[ps].rgProperties[pc].dwPropertyID ==
|
|
rgOutPropertySets[ps].rgProperties[pc].dwPropertyID, TRUE))
|
|
return FALSE;
|
|
if (!CHECK(rgInPropertySets[ps].rgProperties[pc].dwOptions ==
|
|
rgOutPropertySets[ps].rgProperties[pc].dwOptions, TRUE))
|
|
return FALSE;
|
|
// use NULL for DSO interface
|
|
if (!COMPARE(CompareDBID(rgInPropertySets[ps].rgProperties[pc].colid,
|
|
rgOutPropertySets[ps].rgProperties[pc].colid,
|
|
NULL), TRUE))
|
|
return FALSE;
|
|
if (!COMPARE(CompareVariant(&rgInPropertySets[ps].rgProperties[pc].vValue,
|
|
&rgOutPropertySets[ps].rgProperties[pc].vValue), TRUE))
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
} //TCITableDefinition::IsRowsetPropSetPreserved
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Check whether the rowset properties were properly created
|
|
// The rowset properties of the m_pTable are checked against the property set<nl>
|
|
// returned by ITableDefinition::CreateTable method.
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::IsRowsetPropSetCreatedOK
|
|
(
|
|
DBPROPSET *rgOutPropertySets, // the aray returned by ITableDefinition::CreateTable
|
|
ULONG cPropertySets, // the size of the arrays
|
|
IUnknown *pIUnknown // pointer to the rowset interface
|
|
)
|
|
{
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
DBPROPIDSET *rgPropIDSet = NULL;
|
|
DBPROPSET *rgPropertySets = NULL;
|
|
ULONG n;
|
|
BOOL fTestRes = TEST_PASS;
|
|
DBPROPSTATUS ulStatus;
|
|
DBPROPOPTIONS ulOption;
|
|
DBPROPID ulPropID;
|
|
BOOL fSupported;
|
|
BOOL fSettable;
|
|
VARIANT *pvValue;
|
|
|
|
if (!pIUnknown || 0 == cPropertySets || !rgOutPropertySets)
|
|
return TRUE;
|
|
|
|
rgPropIDSet = (DBPROPIDSET*) PROVIDER_ALLOC(sizeof(DBPROPIDSET)*cPropertySets);
|
|
for (n=0; n<cPropertySets; n++)
|
|
{
|
|
// get propID in the property set
|
|
rgPropIDSet[n].guidPropertySet = rgOutPropertySets[n].guidPropertySet;
|
|
rgPropIDSet[n].cPropertyIDs = rgOutPropertySets[n].cProperties;
|
|
if (0 == rgOutPropertySets[n].rgProperties)
|
|
{
|
|
rgPropIDSet[n].rgPropertyIDs = NULL;
|
|
continue;
|
|
}
|
|
else
|
|
SAFE_ALLOC(rgPropIDSet[n].rgPropertyIDs, DBPROPID, rgOutPropertySets[n].cProperties);
|
|
for (ULONG i=0; i<rgOutPropertySets[n].cProperties; i++)
|
|
{
|
|
rgPropIDSet[n].rgPropertyIDs[i] = rgOutPropertySets[n].rgProperties[i].dwPropertyID;
|
|
}
|
|
}
|
|
// get the properties of the rowset
|
|
if (!VerifyInterface(pIUnknown, IID_IRowsetInfo, ROWSET_INTERFACE, (IUnknown**)&pIRowsetInfo))
|
|
{
|
|
fTestRes = TEST_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
else
|
|
{
|
|
m_hr = pIRowsetInfo->GetProperties(cPropertySets, rgPropIDSet, &n, &rgPropertySets);
|
|
ASSERT(n==cPropertySets);
|
|
}
|
|
|
|
if (NULL == rgPropertySets)
|
|
{
|
|
fTestRes = TEST_FAIL;
|
|
goto CLEANUP;
|
|
}
|
|
// check the properties
|
|
for (n=0; n<cPropertySets; n++)
|
|
{
|
|
// get propID in the property set
|
|
if (DBPROPSET_TABLE == rgOutPropertySets[n].guidPropertySet)
|
|
continue;
|
|
if (0 == rgOutPropertySets[n].cProperties)
|
|
continue;
|
|
if (rgPropertySets[n].cProperties != rgOutPropertySets[n].cProperties)
|
|
fTestRes = TEST_FAIL;
|
|
if (NULL == rgOutPropertySets[n].rgProperties)
|
|
continue;
|
|
if (NULL == rgPropertySets[n].rgProperties)
|
|
{
|
|
fTestRes = TEST_FAIL;
|
|
continue;
|
|
}
|
|
// check dbpropstatus
|
|
if (!CHECK(DBPROPSET_ROWSET == rgOutPropertySets[n].guidPropertySet, TRUE))
|
|
{
|
|
for (ULONG i=0; i<rgOutPropertySets[n].cProperties; i++)
|
|
if (!COMPARE(rgOutPropertySets[n].rgProperties[i].dwStatus, DBPROPSTATUS_NOTSUPPORTED))
|
|
fTestRes = TEST_FAIL;
|
|
continue;
|
|
}
|
|
|
|
for (ULONG i=0; i<rgOutPropertySets[n].cProperties; i++)
|
|
{
|
|
ulPropID = rgOutPropertySets[n].rgProperties[i].dwPropertyID;
|
|
ulOption = rgOutPropertySets[n].rgProperties[i].dwStatus;
|
|
ulStatus = rgOutPropertySets[n].rgProperties[i].dwOptions;
|
|
fSupported = SupportedProperty(ulPropID, DBPROPSET_ROWSET);
|
|
fSettable = SettableProperty(ulPropID, DBPROPSET_ROWSET);
|
|
pvValue = &rgOutPropertySets[n].rgProperties[i].vValue;
|
|
|
|
if (!fSupported)
|
|
{
|
|
fTestRes = DBPROPSTATUS_NOTSUPPORTED == ulStatus? fTestRes : TEST_FAIL;
|
|
continue;
|
|
}
|
|
|
|
// property is supported => cannot be sure that setting a prop will fail
|
|
// if is settable, the prop should succeed, unless a bad value is tried
|
|
if (DBPROPSTATUS_OK == ulStatus)
|
|
{
|
|
if (ulPropID != rgOutPropertySets[n].rgProperties[i].dwPropertyID)
|
|
fTestRes = TEST_FAIL;
|
|
if (!CompareVariant(pvValue, &rgOutPropertySets[n].rgProperties[i].vValue))
|
|
{
|
|
fTestRes = TEST_FAIL;
|
|
odtLog << "Rowset property values missmatch for property propID("
|
|
<< rgOutPropertySets[n].rgProperties[i].dwPropertyID << ")\n";
|
|
}
|
|
}
|
|
|
|
switch (ulStatus)
|
|
{
|
|
case DBPROPSTATUS_CONFLICTING:
|
|
fTestRes = (DBPROPOPTIONS_OPTIONAL == ulOption || DBPROPOPTIONS_REQUIRED == ulOption)
|
|
&& pvValue->vt == GetPropInfoType(ulPropID, DBPROPSET_ROWSET)? fTestRes : TEST_FAIL;
|
|
break;
|
|
case DBPROPSTATUS_NOTSET:
|
|
fTestRes = COMPARE(ulOption, DBPROPOPTIONS_OPTIONAL)
|
|
&& pvValue->vt == GetPropInfoType(ulPropID, DBPROPSET_ROWSET)? fTestRes : TEST_FAIL;
|
|
break;
|
|
case DBPROPSTATUS_BADOPTION:
|
|
fTestRes = (DBPROPOPTIONS_OPTIONAL != ulOption)
|
|
&& (DBPROPOPTIONS_REQUIRED)? fTestRes : TEST_FAIL;
|
|
break;
|
|
case DBPROPSTATUS_NOTSETTABLE:
|
|
fTestRes = !fSettable? fTestRes: TEST_FAIL;
|
|
break;
|
|
case DBPROPSTATUS_BADVALUE:
|
|
fTestRes = (VT_EMPTY != pvValue->vt)
|
|
&& (pvValue->vt != GetPropInfoType(ulPropID, DBPROPSET_ROWSET))
|
|
? fTestRes : TEST_FAIL;
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
for (n=0; n<cPropertySets; n++)
|
|
PROVIDER_FREE(rgPropIDSet[n].rgPropertyIDs);
|
|
PROVIDER_FREE(rgPropIDSet);
|
|
FreeProperties( &cPropertySets, &rgPropertySets);
|
|
return fTestRes;
|
|
} //TCITableDefinition::IsRowsetPropSetCreatedOK
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Creates a table with a column of each provider type and returns a rowset
|
|
// to the new created table. The rowset is created with the property required and it
|
|
// is tested
|
|
//--------------------------------------------------------------------------
|
|
int TCITableDefinition::CreateWithOneRowsetProps
|
|
(
|
|
DBPROPID PropID, // Property ID
|
|
DBTYPE DBType, // type of property value
|
|
LPVOID Value, // value to be set
|
|
struct _GUID *pRIID // interface asked on rowset
|
|
)
|
|
{
|
|
DBTYPE rgDBTypes[] = {DBType};
|
|
LPVOID rgValues[] = {Value};
|
|
DBPROPOPTIONS rgOptions[] = {DBPROPOPTIONS_OPTIONAL};
|
|
DBPROPOPTIONS rgOptions2[] = {DBPROPOPTIONS_REQUIRED};
|
|
|
|
|
|
return CreateWithRowsetProps(1, &PropID, rgDBTypes, rgValues, rgOptions, pRIID)
|
|
&& CreateWithRowsetProps(1, &PropID, rgDBTypes, rgValues, rgOptions2, pRIID);
|
|
} //TCITableDefinition::CreateWithOneRowsetProps
|
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Creates a table with a column of each provider type and returns a rowset
|
|
// to the new created table. The rowset is created with the properties required and it
|
|
// is tested
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::CreateWithRowsetProps
|
|
(
|
|
ULONG nProperties, // number of the properties to be set
|
|
DBPROPID *rgPropID, // array with the propIDs
|
|
DBTYPE *rgDBType, // type of property values
|
|
LPVOID *rgValue, // values to be set
|
|
DBPROPOPTIONS *rgOptions, // options of properties
|
|
struct _GUID *pRIID // interface asked on rowset
|
|
)
|
|
{
|
|
BOOL fRes = FALSE;
|
|
DBPROPSET *rgPropertySets = NULL;
|
|
ULONG n, cPropertySets = 0;
|
|
HRESULT hr = E_FAIL;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
BOOL fExists;
|
|
DBID *pTableID = NULL;
|
|
IUnknown *pRowset = NULL; // [out] pointer to outer interface
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
|
|
TESTC(nProperties);
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
for (n=0; n<nProperties; n++)
|
|
{
|
|
SetProperty(&rgPropertySets, &cPropertySets, rgPropID[n],
|
|
rgDBType[n], rgValue[n], rgOptions[n], DB_NULLID, DBPROPSET_ROWSET);
|
|
}
|
|
|
|
|
|
hr = CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc, *pRIID,
|
|
cPropertySets, rgPropertySets, &pTableID, &pRowset);
|
|
|
|
SAFE_RELEASE(pRowset);
|
|
|
|
if ( pTableID
|
|
&& DB_E_NOTABLE != hr
|
|
&& DB_E_DUPLICATETABLEID != hr
|
|
&& CHECK(pTable->DoesTableExist(pTableID, &fExists), S_OK)
|
|
&& fExists)
|
|
CHECK(m_pITableDefinition->DropTable(pTableID), S_OK);
|
|
|
|
delete pTable;
|
|
ReleaseDBID(pTableID);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
odtLog << "Could not create a table with a specified property set.\n";
|
|
if ( (1 == nProperties)
|
|
&& (DBPROPSTATUS_OK != rgPropertySets[0].rgProperties[0].dwStatus)
|
|
&& ( (DBPROPOPTIONS_REQUIRED == rgPropertySets[0].rgProperties[0].dwStatus)
|
|
&& !CHECK(hr, DB_E_ERRORSOCCURRED)))
|
|
{
|
|
odtLog << "wrong value for dwStatus in rowset property";
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
else
|
|
// check the creation of the rowset
|
|
if ( (1 == nProperties)
|
|
&& ( ( (DBPROPSTATUS_OK == rgPropertySets[0].rgProperties[0].dwStatus)
|
|
&& !CHECK(hr, S_OK))
|
|
|| ( (DBPROPSTATUS_OK != rgPropertySets[0].rgProperties[0].dwStatus)
|
|
&& !CHECK(hr, DB_S_ERRORSOCCURRED))))
|
|
{
|
|
odtLog << "wrong value for dwStatus in rowset property";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
fRes = TRUE;
|
|
|
|
CLEANUP:
|
|
FreeProperties( &cPropertySets, &rgPropertySets);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
return fRes;
|
|
} //TCITableDefinition::CreateWithRowsetProps
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// creates a table with not nullable column
|
|
//--------------------------------------------------------------------------
|
|
HRESULT TCITableDefinition::CreateTableWithNoNullableColumns(
|
|
CTable *pTable, // @param [IN] pointer to CTable
|
|
DBCOUNTITEM ulRowCount, // @parm [IN] # of Rows to insert into table, 1 based
|
|
DBORDINAL ulIndex /*=0*/, // @parm [IN] Column Number of index, 1 based (Default=1)
|
|
WCHAR *pwszTableName/*=NULL*/, // @parm [IN] TableName, if NULL call MakeTableName() (Default=NULL)
|
|
EVALUE eValue/*=PRIMARY*/, // @parm [IN] Insert PRIMARY or SECONDARY data (Default=PRIMARY)
|
|
BOOL fFirstUpdateable/*=FALSE*/ // @parm [IN] TRUE means first column will be autoinc (Default=FALSE)
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
// customize the table so that no nullable columns is added
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBORDINAL indexCol;
|
|
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
for (indexCol = 0; indexCol < m_cColumnDesc; indexCol++)
|
|
{
|
|
SetProperty(&rgNewColumnDesc[indexCol].rgPropertySets, &rgNewColumnDesc[indexCol].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
|
|
// by setting DBCOLUMNDESC, all nullable type column are created as nullable
|
|
pTable->SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(pTable->CreateTable(ulRowCount, ulIndex, pwszTableName, eValue, fFirstUpdateable), S_OK);
|
|
|
|
pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition, pTable->GetTableName());
|
|
|
|
hr = S_OK;
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //TCITableDefinition::CreateTableWithNoNullableColumns
|
|
|
|
|
|
|
|
HRESULT TCITableDefinition::AddUniqueConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL ulCol,
|
|
DBDEFERRABILITY Deferrability /*= 0*/
|
|
)
|
|
{
|
|
return AddKeyConstraint(DBCONSTRAINTTYPE_UNIQUE, pTable, 1, &ulCol, Deferrability);
|
|
} //TCITableDefinition::AddUniqueConstraint
|
|
|
|
|
|
|
|
HRESULT TCITableDefinition::AddUniqueConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL cCol,
|
|
DBORDINAL *rgCol,
|
|
DBDEFERRABILITY Deferrability /*= 0*/
|
|
)
|
|
{
|
|
return AddKeyConstraint(DBCONSTRAINTTYPE_UNIQUE, pTable, cCol, rgCol, Deferrability);
|
|
} //TCITableDefinition::AddUniqueConstraint
|
|
|
|
|
|
|
|
HRESULT TCITableDefinition::AddPrimaryKeyConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL ulCol,
|
|
DBDEFERRABILITY Deferrability /*= 0*/
|
|
)
|
|
{
|
|
return AddKeyConstraint(DBCONSTRAINTTYPE_PRIMARYKEY, pTable, 1, &ulCol, Deferrability);
|
|
} //TCITableDefinition::AddPrimaryKeyConstraint
|
|
|
|
|
|
|
|
HRESULT TCITableDefinition::AddPrimaryKeyConstraint(
|
|
CTable *pTable,
|
|
DBORDINAL cCol,
|
|
DBORDINAL *rgCol,
|
|
DBDEFERRABILITY Deferrability /*= 0*/
|
|
)
|
|
{
|
|
return AddKeyConstraint(DBCONSTRAINTTYPE_PRIMARYKEY, pTable, cCol, rgCol, Deferrability);
|
|
} //TCITableDefinition::AddPrimaryKeyConstraint
|
|
|
|
|
|
|
|
HRESULT TCITableDefinition::AddKeyConstraint(
|
|
DBCONSTRAINTTYPE ConstraintType,
|
|
CTable *pTable,
|
|
DBORDINAL cCol,
|
|
DBORDINAL *rgCol,
|
|
DBDEFERRABILITY Deferrability /*= 0*/
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
CCol col;
|
|
CKeyConstraint cons(ConstraintType);
|
|
DBORDINAL ulRow;
|
|
|
|
TESTC(NULL != m_pITDWC);
|
|
TESTC(NULL != pTable);
|
|
TESTC(0 == cCol || NULL != rgCol);
|
|
TESTC(DBCONSTRAINTTYPE_UNIQUE == ConstraintType || DBCONSTRAINTTYPE_PRIMARYKEY == ConstraintType);
|
|
|
|
TESTC_(cons.SetConstraint(pTable, cCol, rgCol, Deferrability), S_OK);
|
|
|
|
TESTC_(pTable->GetColInfo(rgCol[0], col), S_OK);
|
|
|
|
hr = AddConstraintAndCheck(m_pITDWC, &pTable->GetTableID(), cons);
|
|
|
|
// check that inserting a row with duplicate key is not accepted
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ulRow = pTable->GetNextRowNumber();
|
|
// check that you can not add a row to the base table (no nulls are inserted, right?)
|
|
if (S_OK == pTable->Insert(ulRow))
|
|
CHECK(pTable->Insert(ulRow), DB_E_INTEGRITYVIOLATION);
|
|
}
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} // TCITableDefinition::AddKeyConstraint
|
|
|
|
|
|
|
|
HRESULT TCITableDefinition::AddForeignKeyConstraint(
|
|
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 hr = E_FAIL;
|
|
CForeignKeyCons cons;
|
|
DBORDINAL ulRow;
|
|
DBORDINAL index;
|
|
DBORDINAL ulMaxCol;
|
|
|
|
TESTC_(cons.SetConstraint(pBaseTable, cBaseCol, rgBaseCol,
|
|
pReferencedTable, cReferencedCol, rgReferencedCol,
|
|
MatchType, UpdateRule, DeleteRule, Deferrability), S_OK);
|
|
|
|
hr = AddConstraintAndCheck(m_pITDWC, &pBaseTable->GetTableID(), cons);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// find the maximum column of the foreign key
|
|
for (index = 1, ulMaxCol = rgBaseCol[0]; index < cBaseCol; index++)
|
|
{
|
|
ulMaxCol = (ulMaxCol < rgBaseCol[index])? rgBaseCol[index]: ulMaxCol;
|
|
}
|
|
|
|
ulRow = pReferencedTable->GetNextRowNumber();
|
|
ulRow = (ulRow <= ulMaxCol)? ulMaxCol + 1: ulRow;
|
|
// check that you can not add a row to the base table (no nulls are inserted, right?)
|
|
// Note: if there is a NULL column in the foreign key schema this insert
|
|
// rightfully succeeds
|
|
TEST2C_(pBaseTable->Insert(ulRow), DB_E_INTEGRITYVIOLATION, E_FAIL);
|
|
// check that you can add a row to the referenced table
|
|
CHECK(pReferencedTable->Insert(ulRow), S_OK);
|
|
// check that you can now add a row to the base table
|
|
CHECK(pBaseTable->Insert(ulRow), S_OK);
|
|
}
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} // TCITableDefinition::AddForeignKeyConstraint
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
//
|
|
// @cmember Termination function
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCITableDefinition::Terminate()
|
|
{
|
|
DeleteCriticalSection(&m_CriticalSection);
|
|
ULONG nTables;
|
|
nTables = GetNoOfTables();
|
|
ReleaseColumnDesc(m_rgColumnDesc, m_cColumnDesc);
|
|
if (nTables>m_nTables)
|
|
odtLog << "Numer of residual tables: " << nTables-m_nTables << "\n";
|
|
nResidualTables += nTables-m_nTables;
|
|
SAFE_RELEASE(m_pITableDefinition);
|
|
SAFE_RELEASE(m_pITDWC);
|
|
ReleaseDBSession();
|
|
ReleaseDataSourceObject();
|
|
m_ColList.RemoveAll();
|
|
PROVIDER_FREE(m_pwszInvalidTableChars);
|
|
PROVIDER_FREE(m_pwszInvalidColChars);
|
|
return(CSessionObject::Terminate());
|
|
} //TCITableDefinition::Terminate
|
|
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAddColumn)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAddColumn - Testcase for ITableDefinition::AddColumn
|
|
//| Created: 09/10/97
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddColumn::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
//
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table doesn't exist => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_1()
|
|
{
|
|
BOOL fTestRes = TEST_PASS, fExists;
|
|
DBID TableID;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
ULONG cColumnDesc = 1;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
TableID.eKind = DBKIND_NAME;
|
|
// CTable::MakeTableName() generates a name that doesn't exist in the catalog
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// try to add a column on this table that doesn't exist
|
|
if (!CHECK(m_hr = m_pITableDefinition->AddColumn(&TableID, rgColumnDesc, &pColumnID), DB_E_NOTABLE))
|
|
fTestRes = TEST_FAIL;
|
|
|
|
if (!CHECK(m_pTable->DoesTableExist(&TableID, &fExists), S_OK) || fExists)
|
|
{
|
|
odtLog << "Table " << TableID.uName.pwszName << " was added by AddColumn!\n";
|
|
fTestRes = TEST_FAIL;
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc The table is in use => DB_E_TABLEINUSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
IRowset *pIRowset = NULL;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
IRowsetChange *pIRowsetChange2 = NULL;
|
|
HRESULT hr;
|
|
HACCESSOR hAccessor = NULL;
|
|
BYTE *pData = NULL;
|
|
DBCOUNTITEM cBindings = 0;
|
|
DBBINDING *rgBindings = NULL;
|
|
const DBORDINAL cColsToBind = 1;
|
|
LONG_PTR rgColsToBind[cColsToBind];
|
|
HROW *rghRow = NULL;
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
DBPROPSET rgPropSets[1];
|
|
DBPROP rgProperties[1];
|
|
DBLENGTH ulRowSize;
|
|
DBCOUNTITEM nRowNo;
|
|
DBCOUNTITEM nRowsInTable = 0;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
const DBCOUNTITEM nRowsToInsert = 10;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
// ask for a IRowsetChange interface
|
|
m_pTable->SetRowset((IUnknown**)&pIRowsetChange);
|
|
if (SettableProperty(DBPROP_IRowsetChange, DBPROPSET_ROWSET))
|
|
m_pTable->SetRIID((struct _GUID*)&IID_IRowsetChange);
|
|
else
|
|
m_pTable->SetRIID((struct _GUID*)&IID_IRowset);
|
|
|
|
// Set properties
|
|
FILL_PROP_SET(rgPropSets[0], 1, rgProperties, DBPROPSET_ROWSET);
|
|
FILL_PROP(rgProperties[0], DBPROP_OWNINSERT, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
m_pTable->SetPropertySets(rgPropSets, NUMELEM(rgPropSets));
|
|
|
|
// creates the table and populates it, using the returned pIRowsetChange
|
|
TESTC_(hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// check whether iRowsetChange is available
|
|
VerifyInterface(pIRowsetChange, IID_IRowsetChange, ROWSET_INTERFACE, (IUnknown**)&pIRowsetChange2);
|
|
if (pIRowsetChange2)
|
|
{
|
|
for (nRowNo = 0; nRowNo < nRowsToInsert; nRowNo++)
|
|
{
|
|
if (S_OK == Insert(0, (IUnknown*)pIRowsetChange))
|
|
nRowsInTable++;
|
|
}
|
|
}
|
|
|
|
TESTC(VerifyInterface(pIRowsetChange, IID_IRowset, ROWSET_INTERFACE, (IUnknown**)&pIRowset));
|
|
|
|
// get a row
|
|
if (0 < nRowsInTable)
|
|
{
|
|
m_hr = pIRowset->GetNextRows(0, 0, // hChapter & lRowsOffset
|
|
1, // number of rows to be retrieved
|
|
&cRowsObtained, //number of rows actually get
|
|
&rghRow // array of handlers to rows
|
|
);
|
|
if (!CHECK(m_hr, S_OK))
|
|
{
|
|
odtLog << "insuccess on initial IRowset::GetNextRows\n";
|
|
m_hr = pIRowset->ReleaseRows(cRowsObtained, rghRow, NULL, NULL, NULL);
|
|
}
|
|
// test the return value of IRowset::RestartPosition
|
|
CHECK(m_hr = pIRowset->ReleaseRows(cRowsObtained, rghRow, NULL, NULL, NULL), S_OK);
|
|
PROVIDER_FREE(rghRow);
|
|
cRowsObtained = 0;
|
|
}
|
|
else
|
|
odtLog << "Could not insert any row in the table\n";
|
|
|
|
|
|
// check if a column can be added, on the table in use (look for S_OK or DB_E_TABLEINUSE)
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
odtLog << "Column was added while a rowset was still open on table.\n";
|
|
|
|
if (1 > nRowsInTable)
|
|
goto CLEANUP;
|
|
|
|
// see how it reacts to RestartPosition and if the new column can be read
|
|
hr = pIRowset->RestartPosition(0); // a non-chaptered rowset
|
|
if (hr == DB_S_COLUMNSCHANGED)
|
|
{
|
|
odtLog << "DB_S_COLUMNSCHANGED returned on pIRowset->RestartPosition\n";
|
|
|
|
// get the value of the new column in the first row
|
|
//Get an accessor with all the writeable columns
|
|
rgColsToBind[0] = (LONG_PTR)cColumnDesc-1;
|
|
if (!CHECK(hr = GetAccessorAndBindings(
|
|
pIRowset, // pIUnknRowsetObject
|
|
DBACCESSOR_ROWDATA, // accessor flags
|
|
&hAccessor, &rgBindings, &cBindings, // accessor handler, array and number of bindings created
|
|
&ulRowSize, // [OUT] row size
|
|
DBPART_VALUE |DBPART_STATUS |DBPART_LENGTH, // types of bindings to do
|
|
USE_COLS_TO_BIND_ARRAY, // eColsByRef specifies that cols to be bind
|
|
// are given as an array
|
|
FORWARD, // eBindingOrder
|
|
NO_COLS_BY_REF, // eColsByRef
|
|
NULL, NULL,
|
|
NULL, DBTYPE_EMPTY, // ppStringsBufferOut & dwModifier
|
|
1, rgColsToBind // size and array of cols to be bind
|
|
), S_OK))
|
|
{
|
|
odtLog << "problems getting accessor and bindings\n";
|
|
}
|
|
|
|
// alloc memory for the row data
|
|
SAFE_ALLOC(pData, BYTE, ulRowSize);
|
|
|
|
// get the rowset window
|
|
m_hr = pIRowset->GetNextRows(0, 0, // hChapter & lRowsOffset
|
|
1, // number of rows to be retrieved
|
|
&cRowsObtained, //number of rows actually get
|
|
&rghRow // array of handlers to rows
|
|
);
|
|
if (S_OK != m_hr || !COMPARE(1 == cRowsObtained, TRUE))
|
|
{
|
|
odtLog << "after RestartPosition, could not get the rows\n";
|
|
CHECK(m_hr = pIRowset->ReleaseRows(cRowsObtained, rghRow, NULL, NULL, NULL), S_OK);
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// read data
|
|
CHECK(m_hr = pIRowset->GetData(rghRow[0], hAccessor, pData), S_OK);
|
|
if ((S_OK != m_hr) ||
|
|
((DBSTATUS_S_OK != ((DATA*)pData)->sStatus) &&
|
|
!COMPARE(DBSTATUS_S_ISNULL == ((DATA*)pData)->sStatus, TRUE) ))
|
|
{
|
|
odtLog << "can't get the data from the newly created column\n";
|
|
}
|
|
else
|
|
odtLog << "data read!\n";
|
|
CHECK(m_hr = pIRowset->ReleaseRows(cRowsObtained, rghRow, NULL, NULL, NULL), S_OK);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
odtLog << "DB_E_TABLEINUSE was returned when a column was to be added on a table whith an open rowset.\n";
|
|
CHECK(hr, DB_E_TABLEINUSE);
|
|
}
|
|
|
|
CLEANUP:
|
|
m_pTable->SetRowset(NULL);
|
|
SAFE_RELEASE(pIRowsetChange2);
|
|
SAFE_RELEASE(pIRowset);
|
|
SAFE_FREE(pData);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
m_pTable->SetNoOfPropertySets(0);
|
|
m_pTable->SetPropertySets(NULL);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
FreeAccessorBindings(cBindings, rgBindings);
|
|
SAFE_FREE(pData);
|
|
SAFE_FREE(rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pTableID = DB_NULLID => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_3()
|
|
{
|
|
BOOL fTestRes = TEST_PASS;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
ULONG cColumnDesc = 1;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// try to add a column from this table that doesn't exist
|
|
if (!CHECK(m_pITableDefinition->AddColumn((DBID*)&DB_NULLID, rgColumnDesc, &pColumnID), DB_E_NOTABLE))
|
|
fTestRes = TEST_FAIL;
|
|
|
|
ReleaseDBID(pColumnID);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID = NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_4()
|
|
{
|
|
BOOL fTestRes = TEST_PASS;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
ULONG cColumnDesc = 1;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// try to add a column from this table that doesn't exist
|
|
if (!CHECK(m_hr = m_pITableDefinition->AddColumn(NULL, rgColumnDesc, &pColumnID), E_INVALIDARG))
|
|
fTestRes = TEST_FAIL;
|
|
|
|
ReleaseDBID(pColumnID);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length for table name => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_5()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = BuildValidName(m_cMaxTableName, m_pTable->GetTableName());
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
PRVTRACE(L"***TCADDColumn::Variation_5(): TableName=%s, len=%d\n",
|
|
TableID.uName.pwszName, wcslen(TableID.uName.pwszName));
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0, TableID.uName.pwszName), S_OK);
|
|
|
|
// try to add a column to this maximum length name table
|
|
// prepare the column to be added
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1], &pColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(&TableID, FALSE); // don't want to release the pointer, just the container
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc the table name is 1 char too long => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_6()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBID *pColumnID = NULL;
|
|
WCHAR *pwszTableName;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
GetLiteralInfo();
|
|
TableID.uName.pwszName = BuildValidName(m_cMaxTableName, m_pTable->GetTableName());
|
|
pwszTableName = BuildValidName(m_cMaxTableName+1, m_pTable->GetTableName());
|
|
// prepare arguments for table creation
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
PRVTRACE(L"***TCADDColumn::Variation_6(): TableName=%s, len=%d\n", TableID.uName.pwszName,
|
|
wcslen(TableID.uName.pwszName));
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0, TableID.uName.pwszName), S_OK);
|
|
|
|
// try to add a column, spec the table name plus a char as a table name
|
|
PROVIDER_FREE(TableID.uName.pwszName);
|
|
TableID.uName.pwszName = pwszTableName;
|
|
TESTC_(AddColumnAndCheck(&TableID, &rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid table name => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_7()
|
|
{
|
|
BOOL fTestRes = TEST_PASS;
|
|
DBID TableID;
|
|
DBID *pColumnID = NULL;
|
|
size_t m, n;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
ULONG cColumnDesc = 1;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
m = min(m_cMaxTableName, n=5+wcslen(m_pTable->GetTableName()));
|
|
TableID.uName.pwszName = BuildInvalidName(m, m_pTable->GetTableName(), m_pwszInvalidTableChars);
|
|
PRVTRACE(L"***TCADDColumn::Variation_7(): TableName=%s, len=%d\n", TableID.uName.pwszName,
|
|
wcslen(TableID.uName.pwszName));
|
|
|
|
if (!CHECK(m_hr = m_pITableDefinition->AddColumn(&TableID, &rgColumnDesc[0], &pColumnID), DB_E_NOTABLE))
|
|
fTestRes = TEST_FAIL;
|
|
|
|
ReleaseDBID(pColumnID);
|
|
ReleaseDBID(&TableID, FALSE);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc->dbcid = DB_NULLID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_8()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a DB_NULLID colid to this table
|
|
if (rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName);
|
|
memcpy(&rgColumnDesc[cColumnDesc-1].dbcid, (DBID*)&DB_NULLID, sizeof(DBID));
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Column name pointer is NULL => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a NULL value for name pointer
|
|
if (rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName);
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = NULL;
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc column name is an empty string => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_10()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
// create a table with cColumnDesc-1 columns
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a NULL value for name pointer
|
|
if (rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName);
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = wcsDuplicate(L"");
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length of column name => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_11()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
WCHAR *pwszName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->MakeTableName(NULL);
|
|
pwszName = wcsDuplicate(m_pTable->GetTableName());
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a maximum size for column name
|
|
if (rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName);
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = BuildValidName(m_cMaxColName, pwszName);
|
|
odtLog << "A maximum length column name: " << rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName <<
|
|
", length=" << wcslen(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName) << "\n";
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
PROVIDER_FREE(pwszName);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 1-char-too-long column name => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_12()
|
|
{
|
|
TBEGIN
|
|
WCHAR *pwszName = NULL;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->MakeTableName(NULL);
|
|
pwszName = wcsDuplicate(m_pTable->GetTableName());
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a name too long
|
|
if (rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName);
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = BuildValidName(m_cMaxColName+1, pwszName);
|
|
odtLog << "A 1 char too long column name: " << rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName <<
|
|
", length=" << wcslen(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName) << "\n";
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
SAFE_FREE(pwszName);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add a column for each provider type, maximum column size => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_13()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBORDINAL i;
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
DuplicateColumnDesc(rgColumnDesc, 1, &pColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName);
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"FirstColumn");
|
|
// for each type in DBCOLUMNDESC, add a column with maximum column size
|
|
SetMaximumColSize(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
// create a table with a single column, equal to the first one in the row
|
|
CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
if (FAILED(m_hr))
|
|
continue;
|
|
|
|
// try to add a column from rgColumnDesc[i]
|
|
odtLog << "column name:" << rgColumnDesc[i].dbcid.uName.pwszName <<
|
|
" column type:" << rgColumnDesc[i].pwszTypeName << "\n";
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i],
|
|
&pColumnID), S_OK);
|
|
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add a column for each known type; ulColumnsize == 0 => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_14()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBORDINAL i;
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
DuplicateColumnDesc(rgColumnDesc, 1, &pColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName);
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"FirstColumn");
|
|
SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
// for each type in DBCOLUMNDESC, add a column with maximum column size
|
|
m_pTable->SetColumnDesc(NULL);
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
// create a table with a single column, equal to the first one in the row
|
|
CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
if (FAILED(m_hr))
|
|
continue;
|
|
|
|
// try to add a column from rgColumnDesc[i]
|
|
odtLog << "column name:" << rgColumnDesc[i].dbcid.uName.pwszName <<
|
|
" column type:" << rgColumnDesc[i].pwszTypeName << "\n";
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i],
|
|
&pColumnID), S_OK);
|
|
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//--------------------------------------------------------------------
|
|
// @mfunc Add a column for each provider type (table is populated) => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_15()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBORDINAL i;
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
DuplicateColumnDesc(rgColumnDesc, 1, &pColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName);
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"FirstColumn");
|
|
|
|
m_pTable->SetColumnDesc(NULL);
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
// try to add a column from rgColumnDesc[i]
|
|
odtLog << "column name:" << rgColumnDesc[i].dbcid.uName.pwszName <<
|
|
" column type:" << rgColumnDesc[i].pwszTypeName << "\n";
|
|
|
|
// create a popoulated table
|
|
if (!CHECK(m_pTable->CreateTable(10, 0), S_OK))
|
|
continue;
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i],
|
|
&pColumnID), S_OK);
|
|
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Precision testing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_16()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBORDINAL i;
|
|
WCHAR *pwszColumnName = NULL;
|
|
BYTE precision, p[6];
|
|
ULONG nmax = 6;
|
|
WCHAR *prefix[]={L"zero", L"one", L"half", L"max", L"big", L"extra"};
|
|
HRESULT hres;
|
|
DBCOLUMNDESC *rgColDesc = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
DuplicateColumnDesc(rgColumnDesc, 1, &rgColDesc);
|
|
m_pTable->SetColumnDesc(rgColDesc, 1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
SAFE_FREE(rgColDesc[0].dbcid.uName.pwszName);
|
|
rgColDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"initialColumn");
|
|
|
|
// for each type in DBCOLUMNDESC, add a column with different precision value
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
|
|
// try to add a column with different precision values
|
|
odtLog << "column name:" << rgColumnDesc[i].dbcid.uName.pwszName <<
|
|
" column type:" << rgColumnDesc[i].pwszTypeName << "\n";
|
|
precision = rgColumnDesc[i].bPrecision; // BuildColumnDesc puts max val in bPrecision!
|
|
p[0] = 0;
|
|
p[1] = 1;
|
|
p[2] = precision/2;
|
|
p[3] = precision;
|
|
if (precision > 254)
|
|
nmax = 4;
|
|
p[4] = precision+1;
|
|
p[5] = (ULONG)precision+10>255? 255: precision+10;
|
|
|
|
pwszColumnName = rgColumnDesc[i].dbcid.uName.pwszName;
|
|
rgColumnDesc[i].dbcid.uName.pwszName = NULL;
|
|
|
|
rgColumnDesc[i].bScale = 0;
|
|
rgColumnDesc[i].ulColumnSize = 0;
|
|
|
|
for (ULONG j=0; j<nmax; j++)
|
|
{
|
|
odtLog << "\t" << p[j];
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// if needed you can limit wcscat with the max length for col size
|
|
rgColumnDesc[i].dbcid.uName.pwszName = (WCHAR*) PROVIDER_ALLOC( sizeof(WCHAR) * m_cMaxColName);
|
|
wcscpy(rgColumnDesc[i].dbcid.uName.pwszName, prefix[j]);
|
|
wcsncat(rgColumnDesc[i].dbcid.uName.pwszName, pwszColumnName, m_cMaxColName-wcslen(prefix[j]));
|
|
rgColumnDesc[i].bPrecision = p[j];
|
|
hres = S_OK;
|
|
if (rgColumnDesc[i].wType == DBTYPE_NUMERIC && ((j>3) || (j==0)) )
|
|
hres = DB_E_BADPRECISION;
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[i], &pColumnID), hres);
|
|
|
|
SAFE_FREE(rgColumnDesc[i].dbcid.uName.pwszName);
|
|
rgColumnDesc[i].dbcid.uName.pwszName = NULL;
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
}
|
|
odtLog << "\n";
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Scale testing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_17()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBORDINAL i;
|
|
WCHAR *pwszName;
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
DuplicateColumnDesc(rgColumnDesc, 1, &pColumnDesc);
|
|
//SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName);
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"Initial_column");
|
|
// create a table with a single column, equal to the first one in the row
|
|
m_pTable->SetColumnDesc(NULL); // so that m_pTable->rgColumnDesc will not be deallocated next
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
// for each type in DBCOLUMNDESC, add a column with different precision value
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
if (!SUCCEEDED(m_hr))
|
|
continue;
|
|
|
|
odtLog << "column name: " << rgColumnDesc[i].dbcid.uName.pwszName <<
|
|
" column type: " << rgColumnDesc[i].pwszTypeName << "\n";
|
|
|
|
if ( rgColumnDesc[i].wType == DBTYPE_NUMERIC
|
|
|| rgColumnDesc[i].wType == DBTYPE_DECIMAL
|
|
|| rgColumnDesc[i].wType == DBTYPE_VARNUMERIC )
|
|
{
|
|
const int nScales = 7;
|
|
BYTE smax, smin, p[nScales], s[nScales], precision;
|
|
ULONG nmax = 1;
|
|
WCHAR *prefix[]={L"zero", L"min", L"half", L"max", L"maxpp", L"prec", L"extra_prec"};
|
|
HRESULT hres[nScales] = {S_OK, S_OK, S_OK, S_OK, S_OK, S_OK, S_OK};
|
|
CCol col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
|
|
// try to add a column with different scale values
|
|
smin = (BYTE)col.GetMinScale();
|
|
smax = (BYTE)col.GetMaxScale();
|
|
precision = (BYTE)col.GetPrecision();
|
|
for (ULONG k=0; k<nScales; p[k++]=precision);
|
|
s[0] = 0;
|
|
hres[0] = (smin==0)? S_OK: DB_E_BADSCALE;
|
|
if (smin > 0)
|
|
{
|
|
s[1] = smin;
|
|
nmax++;
|
|
}
|
|
s[nmax++] = (smin+smax)/2;
|
|
s[nmax++] = smax;
|
|
if (smax < 255)
|
|
{
|
|
s[nmax] = smax+1;
|
|
hres[nmax++] = DB_E_BADSCALE;
|
|
// check matching the precision
|
|
s[nmax] = precision;
|
|
hres[nmax] = (precision>smax) ? DB_E_BADSCALE: S_OK;
|
|
nmax++;
|
|
s[nmax] = p[nmax]+1;
|
|
hres[nmax++]= DB_E_BADSCALE;
|
|
}
|
|
|
|
pwszName = rgColumnDesc[i].dbcid.uName.pwszName;
|
|
rgColumnDesc[i].dbcid.uName.pwszName = NULL; // protection for inside the loop!
|
|
for (ULONG j=0; j<nmax; j++)
|
|
{
|
|
odtLog << "\t" << s[j];
|
|
|
|
// if needed you can limit wcscat with the max length for col size
|
|
if (rgColumnDesc[i].dbcid.uName.pwszName)
|
|
SAFE_FREE(rgColumnDesc[i].dbcid.uName.pwszName);
|
|
rgColumnDesc[i].dbcid.uName.pwszName = (WCHAR*) PROVIDER_ALLOC( sizeof(WCHAR) * m_cMaxColName);
|
|
wcscpy(rgColumnDesc[i].dbcid.uName.pwszName, prefix[j]);
|
|
wcsncat(rgColumnDesc[i].dbcid.uName.pwszName, pwszName, m_cMaxColName-wcslen(prefix[j]));
|
|
rgColumnDesc[i].bPrecision = p[j];
|
|
rgColumnDesc[i].bScale = s[j];
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[i], &pColumnID), hres[j]);
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
}
|
|
odtLog << "\n";
|
|
SAFE_FREE(pwszName);
|
|
}
|
|
else
|
|
{
|
|
rgColumnDesc[i].bScale = 128;
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[i], &pColumnID), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
}
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetNoOfColumnDesc(1);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid value for the property of a column => DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_18()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBPROPID dwPropID = DBPROP_COL_UNIQUE;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a bad property value (prop of a different type than expected)
|
|
SetProperty(&rgColumnDesc[cColumnDesc-1].rgPropertySets,
|
|
&rgColumnDesc[cColumnDesc-1].cPropertySets,
|
|
dwPropID,
|
|
VT_I2, (LPVOID)12,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_ERRORSOCCURRED);
|
|
TESTC(VerifyPropStatus(rgColumnDesc[cColumnDesc-1].cPropertySets,
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets, dwPropID, DBPROPSET_COLUMN,
|
|
DBPROPSTATUS_BADVALUE));
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Non-column property => DBPROPSTATUS_NOTSUPPORTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_19()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBPROPID dwPropID = DBPROP_COL_UNIQUE;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a bad property guid (DBPROPSET_INDEX)
|
|
SetProperty(
|
|
&rgColumnDesc[cColumnDesc-1].rgPropertySets, &rgColumnDesc[cColumnDesc-1].cPropertySets,
|
|
dwPropID,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_OPTIONAL, DB_NULLID, DBPROPSET_INDEX);
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_S_ERRORSOCCURRED);
|
|
TESTC(VerifyPropStatus(rgColumnDesc[cColumnDesc-1].cPropertySets,
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets, dwPropID, DBPROPSET_INDEX, DBPROPSTATUS_NOTSUPPORTED));
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent property => DBPROPSTATUS_NOTSUPPORTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_20()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a bad property id
|
|
SetProperty(&rgColumnDesc[cColumnDesc-1].rgPropertySets,
|
|
&rgColumnDesc[cColumnDesc-1].cPropertySets, 0xffffffff, VT_BOOL, (LPVOID)VARIANT_TRUE);
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_S_ERRORSOCCURRED);
|
|
|
|
TESTC(VerifyPropStatus(rgColumnDesc[cColumnDesc-1].cPropertySets,
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets, 0xffffffff,
|
|
DBPROPSET_COLUMN, DBPROPSTATUS_NOTSUPPORTED));
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad option => DBPROPSTATUS_BADOPTION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_21()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBPROPID dwPropID = DBPROP_COL_NULLABLE;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a bad option
|
|
SetProperty(&rgColumnDesc[cColumnDesc-1].rgPropertySets, &rgColumnDesc[cColumnDesc-1].cPropertySets,
|
|
dwPropID,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
0xf0);
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_ERRORSOCCURRED);
|
|
|
|
TESTC(VerifyPropStatus(rgColumnDesc[cColumnDesc-1].cPropertySets,
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets, dwPropID,
|
|
DBPROPSET_COLUMN,DBPROPSTATUS_BADOPTION));
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Conflicting property => DBPROPSTATUS_CONFLICTING
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_22()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBORDINAL i, nCol;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
ULONG nConfStatus = 0;
|
|
ULONG nOKStatus = 0;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_COL_PRIMARYKEY, DBPROPSET_COLUMN)
|
|
&& SettableProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
nCol = cColumnDesc;
|
|
for (i=0; i< cColumnDesc; i++)
|
|
{
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
if (col.GetNullable()!=0)
|
|
nCol = i;
|
|
}
|
|
|
|
TESTC(nCol < cColumnDesc);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
// try to add a column with conflicting properties
|
|
PROVIDER_FREE(rgColumnDesc[nCol].dbcid.uName.pwszName);
|
|
rgColumnDesc[nCol].dbcid.uName.pwszName = wcsDuplicate(L"MyColumn");
|
|
SetProperty(&rgColumnDesc[nCol].rgPropertySets, &rgColumnDesc[nCol].cPropertySets,
|
|
DBPROP_COL_PRIMARYKEY, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
SetProperty(&rgColumnDesc[nCol].rgPropertySets, &rgColumnDesc[nCol].cPropertySets,
|
|
DBPROP_COL_NULLABLE, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[nCol], &pColumnID), DB_E_ERRORSOCCURRED);
|
|
|
|
if (DBPROPSTATUS_CONFLICTING == rgColumnDesc[nCol].rgPropertySets[0].rgProperties[0].dwStatus)
|
|
nConfStatus++;
|
|
else
|
|
{
|
|
TESTC(DBPROPSTATUS_OK == rgColumnDesc[nCol].rgPropertySets[0].rgProperties[0].dwStatus);
|
|
}
|
|
|
|
if (DBPROPSTATUS_CONFLICTING == rgColumnDesc[nCol].rgPropertySets[0].rgProperties[1].dwStatus)
|
|
nConfStatus++;
|
|
else
|
|
{
|
|
TESTC(DBPROPSTATUS_OK == rgColumnDesc[nCol].rgPropertySets[0].rgProperties[1].dwStatus);
|
|
}
|
|
|
|
TESTC(0 < nConfStatus);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//--------------------------------------------------------------------
|
|
// @mfunc Bad column ID for a property => ignored
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_23()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBID colID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBORDINAL cCol;
|
|
CCol col;
|
|
BOOL fFound = FALSE;
|
|
BOOL fExists;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
for (cCol=0; cCol < m_cColumnDesc; cCol++)
|
|
{
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[cCol]), rgColumnDesc[cCol].wType, &fExists);
|
|
fFound = fExists && 1 == col.GetNullable();
|
|
break;
|
|
}
|
|
|
|
TESTC_PROVIDER(fFound && SupportedProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN));
|
|
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a property that set coldid to smthg different from DB_NULLID
|
|
colID.eKind = DBKIND_NAME;
|
|
colID.uName.pwszName = wcsDuplicate(L"bogus");
|
|
SetProperty(&rgColumnDesc[cCol].rgPropertySets, &rgColumnDesc[cCol].cPropertySets,
|
|
DBPROP_COL_NULLABLE, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL, colID);
|
|
if (DBKIND_NAME == rgColumnDesc[cCol].dbcid.eKind && rgColumnDesc[cCol].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[cCol].dbcid.uName.pwszName);
|
|
rgColumnDesc[cCol].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[cCol].dbcid.uName.pwszName = wcsDuplicate(L"ExtraColumn");
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cCol],
|
|
&pColumnID), S_OK);
|
|
|
|
TESTC(VerifyPropStatus(rgColumnDesc[cCol].cPropertySets,
|
|
rgColumnDesc[cCol].rgPropertySets, DBPROP_COL_NULLABLE,
|
|
DBPROPSET_COLUMN, DBPROPSTATUS_OK));
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(pColumnID);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad column type (wType in DBCOLUMNDESC)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_24()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(10, 0), S_OK);
|
|
// try to add a column with a bad wType
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].pwszTypeName);
|
|
rgColumnDesc[cColumnDesc-1].pwszTypeName = NULL;
|
|
rgColumnDesc[cColumnDesc-1].wType = 0xFFFF;
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADTYPE);
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(pColumnID);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid provider type name for a column => DB_E_BADTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_25()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(10, 0), S_OK);
|
|
// try to add a column with a bad wType
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].pwszTypeName);
|
|
rgColumnDesc[cColumnDesc-1].pwszTypeName = wcsDuplicate(L"New_type_name");
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADTYPE);
|
|
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL ppColumnDesc => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_26()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a bad wType
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Autoincrementable column - DBPROP_COL_AUTOINCREMENT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_27()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
DBORDINAL i;
|
|
CCol col;
|
|
HRESULT hres1; // for DBPROP_COL_AUTOINCREMENT set to VARIANT_TRUE
|
|
HRESULT hres2; // for DBPROP_COL_AUTOINCREMENT set to VARIANT_FALSE
|
|
HRESULT hr;
|
|
BOOL fReadOnlyAutoInc;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
BOOL fSupported = TRUE;
|
|
ULONG ulStatus,
|
|
cPropSet,
|
|
cProp;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
fReadOnlyAutoInc = !SettableProperty(DBPROP_COL_AUTOINCREMENT, DBPROPSET_COLUMN);
|
|
fSupported = SupportedProperty(DBPROP_COL_AUTOINCREMENT, DBPROPSET_COLUMN);
|
|
if (!fSupported)
|
|
odtLog << "DBPROP_COL_AUTOINCREMENT is NOT SUPPORTED!\n";
|
|
DuplicateColumnDesc(&rgColumnDesc[0], 1, &pColumnDesc);
|
|
|
|
SAFE_FREE(pColumnDesc->dbcid.uName.pwszName)
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"First_column");
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
if (fSupported)
|
|
{
|
|
hres1 = (col.CanAutoInc()) ? S_OK : DB_E_ERRORSOCCURRED;
|
|
hres2 = (!col.CanAutoInc() || !fReadOnlyAutoInc) ? S_OK : DB_E_ERRORSOCCURRED;
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i])
|
|
<< ((col.CanAutoInc()) ? " is AUTOINCREMENTABLE\n" : " is NOT autoincrementable\n");
|
|
}
|
|
else
|
|
{
|
|
hres1 = hres2 = DB_E_ERRORSOCCURRED;
|
|
}
|
|
|
|
if (!CHECK(m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as an AUTOINCREMENT COLUMN
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_AUTOINCREMENT, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED,
|
|
DB_NULLID, DBPROPSET_COLUMN, &cPropSet, &cProp);
|
|
rgColumnDesc[i].bScale = 0;
|
|
|
|
CHECK(hr = AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[i], NULL), hres1);
|
|
|
|
odtLog << (SUCCEEDED(hr) ? "\tautoinc column added\n" : "\tautoinc column could not be added\n");
|
|
//check the state
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus;
|
|
if (S_OK == hr)
|
|
{
|
|
COMPARE(ulStatus, DBPROPSTATUS_OK);
|
|
COMPARE(fSupported, TRUE);
|
|
COMPARE(col.CanAutoInc(), TRUE);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
|
|
if (!fSupported)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fReadOnlyAutoInc)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
else
|
|
COMPARE(ulStatus, DBPROPSTATUS_BADVALUE);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
|
|
if (!CHECK(m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as an non autoincrement column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_AUTOINCREMENT, VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_REQUIRED);
|
|
rgColumnDesc[i].bScale = 0;
|
|
CHECK(hr = AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[i], NULL), hres2);
|
|
|
|
odtLog << (SUCCEEDED(hr) ? "\tNOT autoinc column added\n" : "\tNOT autoinc column could not be added\n");
|
|
// check the returned status
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[0].rgProperties[0].dwStatus;
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
COMPARE(ulStatus, DBPROPSTATUS_OK);
|
|
COMPARE(fSupported, TRUE);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
COMPARE(!col.CanAutoInc(), TRUE);
|
|
|
|
if (!fSupported)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fReadOnlyAutoInc)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
else
|
|
COMPARE(ulStatus, DBPROPSTATUS_BADVALUE);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
}
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_DEFAULT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_28()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *pColumnDesc=NULL;
|
|
DBORDINAL i;
|
|
HRESULT hr;
|
|
VARIANT value;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
BOOL fSettable = TRUE;
|
|
BOOL fSupported = TRUE;
|
|
ULONG ulStatus;
|
|
|
|
pTable->CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
DuplicateColumnDesc(&rgColumnDesc[0], 1, &pColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName);
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"First_column");
|
|
ASSERT(pColumnDesc->dbcid.uName.pwszName);
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
if (!SupportedProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
{
|
|
odtLog << "DBPROP_COL_DEFAULT is NOT SUPPORTED.\n";
|
|
fSettable = FALSE;
|
|
fSupported = FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (!SettableProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
fSettable = FALSE;
|
|
}
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i]);
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a column with a default value
|
|
VariantInit(&value);
|
|
GetDefaultValue(&rgColumnDesc[i], &value, pTable);
|
|
SetDefaultProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
&value, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&value);
|
|
//rgColumnDesc[i].ulColumnSize = 0;
|
|
|
|
// since the property could be supported, writeable but unavailable for
|
|
// certain data types, a return value cannot be enforced
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[0].rgProperties[0].dwStatus;
|
|
if (S_OK == hr)
|
|
{
|
|
odtLog << "\t: column has been added with a DEFAULT VALUE\n";
|
|
COMPARE(ulStatus, DBPROPSTATUS_OK);
|
|
COMPARE(fSupported, TRUE);
|
|
}
|
|
else
|
|
{
|
|
if (CHECK(hr, DB_E_ERRORSOCCURRED))
|
|
{
|
|
odtLog << "\t: column was added WITHOUT default value\n";
|
|
if (!fSupported)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
// property could be settable but failing for this data type
|
|
else if (fSettable)
|
|
COMPARE(ulStatus, DBPROPSTATUS_BADVALUE);
|
|
else
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
else
|
|
{
|
|
odtLog << "\tERROR: column was NOT added\n";
|
|
}
|
|
}
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
// the vt type of the default property could cause problems in VariantClear
|
|
// call PrepareVariantToClear to check and fix
|
|
FreeProperties( &rgColumnDesc[i].cPropertySets, &rgColumnDesc[i].rgPropertySets);
|
|
}
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
delete pTable;
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_DESCRIPTION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_29()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
WCHAR *pwszName = NULL;
|
|
HRESULT hr;
|
|
BSTR pwszDescription = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
HRESULT hExpRes = S_OK;
|
|
BOOL fSettable = TRUE;
|
|
BOOL fSupported = TRUE;
|
|
ULONG ulStatus,
|
|
cPropSet,
|
|
cProp;
|
|
|
|
if (!SupportedProperty(DBPROP_COL_DESCRIPTION, DBPROPSET_COLUMN))
|
|
{
|
|
odtLog << "DBPROP_COL_DESCRIPTION is NOT SUPPORTED.\n";
|
|
hExpRes = DB_S_ERRORSOCCURRED;
|
|
fSettable = FALSE;
|
|
fSupported = FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (!SettableProperty(DBPROP_COL_DESCRIPTION, DBPROPSET_COLUMN))
|
|
{
|
|
fSettable = FALSE;
|
|
odtLog << "Implementing the desricption property as readonly is strange. Please reconsider!\n";
|
|
}
|
|
}
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
//SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
pwszName = rgColumnDesc[0].dbcid.uName.pwszName;
|
|
m_pTable->SetColumnDesc(rgColumnDesc, 1);
|
|
pwszDescription = SysAllocString(L"ColumnDescription");
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << "column of type " << rgColumnDesc[i].pwszTypeName;
|
|
|
|
rgColumnDesc[0].dbcid.uName.pwszName = L"First_column";
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
{
|
|
if (SUCCEEDED(m_hr))
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
continue;
|
|
}
|
|
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszName;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_DESCRIPTION, DBTYPE_BSTR, (LPVOID)pwszDescription, DBPROPOPTIONS_OPTIONAL,
|
|
DB_NULLID, DBPROPSET_COLUMN, &cPropSet, &cProp);
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
|
|
if (!fSupported)
|
|
CHECK(hr, DB_S_ERRORSOCCURRED);
|
|
else if (fSettable)
|
|
CHECK(hr, S_OK);
|
|
else if (S_OK != hr)
|
|
CHECK(hr, DB_S_ERRORSOCCURRED);
|
|
|
|
if (SUCCEEDED(hr))
|
|
odtLog << ((DB_S_ERRORSOCCURRED == hr) ? ": could not add a description\n" :
|
|
": description has been added\n");
|
|
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus;
|
|
if (!fSupported)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fSettable)
|
|
COMPARE(ulStatus, DBPROPSTATUS_OK);
|
|
else
|
|
COMPARE(ulStatus, DBPROPSTATUS_BADVALUE);
|
|
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
}
|
|
|
|
SysFreeString(pwszDescription);
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszName;
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_FIXEDLENGTH
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_30()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
BOOL fFixedLength;
|
|
DBORDINAL i;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
BOOL fSettable = TRUE;
|
|
BOOL fSupported = TRUE;
|
|
ULONG ulStatus,
|
|
cPropSet,
|
|
cProp;
|
|
|
|
if (!SupportedProperty(DBPROP_COL_FIXEDLENGTH, DBPROPSET_COLUMN))
|
|
{
|
|
odtLog << "DBPROP_COL_FIXEDLENGTH is NOT SUPPORTED\n";
|
|
fSettable = FALSE;
|
|
fSupported = FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (!SettableProperty(DBPROP_COL_FIXEDLENGTH, DBPROPSET_COLUMN))
|
|
fSettable = FALSE;
|
|
}
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
DuplicateColumnDesc(&rgColumnDesc[0], 1, &pColumnDesc);
|
|
SetMaximumColSize(rgColumnDesc, cColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName)
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"First_column");
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
if ( DBTYPE_STR != rgColumnDesc[i].wType
|
|
&& DBTYPE_WSTR != rgColumnDesc[i].wType
|
|
&& DBTYPE_BYTES != rgColumnDesc[i].wType)
|
|
continue;
|
|
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
// just not yet implemented
|
|
// pending for all providers to adjust the provider types schema rowset
|
|
fFixedLength = col.GetIsFixedLength();
|
|
if (fFixedLength)
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i]) <<" is fixed length\n";
|
|
else
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i]) <<" is variable length\n";
|
|
|
|
if (!CHECK(m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a fixed length column
|
|
odtLog << "\ttry to add a fixed length column: ";
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_FIXEDLENGTH, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED,
|
|
DB_NULLID, DBPROPSET_COLUMN, &cPropSet, &cProp);
|
|
rgColumnDesc[i].bScale = 0;
|
|
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus;
|
|
if (S_OK == hr)
|
|
COMPARE(ulStatus, DBPROPSTATUS_OK);
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
|
|
if (!fSupported)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fSettable)
|
|
COMPARE(ulStatus, DBPROPSTATUS_BADVALUE);
|
|
else if (!fSettable)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
|
|
odtLog << ((S_OK == hr)? "ok\n" : "failed\n");
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
|
|
if (!CHECK(m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a variable_length
|
|
odtLog << "\ttry to add a variable length column: ";
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_FIXEDLENGTH, VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_REQUIRED,
|
|
DB_NULLID, DBPROPSET_COLUMN, &cPropSet, &cProp);
|
|
rgColumnDesc[i].bScale = 0;
|
|
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[i], NULL);
|
|
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus;
|
|
if (S_OK == hr)
|
|
COMPARE(ulStatus, DBPROPSTATUS_OK);
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
if (!fSupported)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fSettable)
|
|
COMPARE(ulStatus, DBPROPSTATUS_BADVALUE);
|
|
else
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
|
|
odtLog << ((S_OK == hr)? "ok\n" : "failed\n");
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_NULLABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_31()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
BOOL fNotNullable, fNullable;
|
|
DBORDINAL i;
|
|
VARIANT value, defval;
|
|
CCol col;
|
|
HRESULT hr;
|
|
DBPROP *pProp = NULL;
|
|
DBPROP *pPropDefault = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
BOOL fSettable = TRUE;
|
|
BOOL fSupported = TRUE;
|
|
ULONG ulStatus,
|
|
cPropSet,
|
|
cProp;
|
|
|
|
if (!SupportedProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN))
|
|
{
|
|
odtLog << "DBPROP_COL_NULLABLE is NOT SUPPORTED\n";
|
|
fSettable = FALSE;
|
|
fSupported = FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (!SettableProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN))
|
|
fSettable = FALSE;
|
|
}
|
|
|
|
pTable->CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
DuplicateColumnDesc(&rgColumnDesc[0], 1, &pColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName)
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"First_column");
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
value.vt = VT_BOOL;
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
fNotNullable = FALSE;
|
|
fNullable = FALSE;
|
|
switch (col.GetNullable())
|
|
{
|
|
case 1:
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i]) <<" is nullable: \n";
|
|
fNullable = TRUE;
|
|
break;
|
|
case 0:
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i]) <<" is not nullable: \n";
|
|
fNotNullable = TRUE;
|
|
break;
|
|
default:
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i]) <<": nullable/not nullable information was not found\n";
|
|
break;
|
|
}
|
|
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a nullable one
|
|
//odtLog << "try to add a nullable column\n";
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_NULLABLE, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED, DB_NULLID,
|
|
DBPROPSET_COLUMN, &cPropSet, &cProp);
|
|
rgColumnDesc[i].bScale = 0;
|
|
|
|
// try to add a column but do not require the seccess of the operation
|
|
// though the column is declared nullable, adding a column could be unimplemented in the provider
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
|
|
if (fNullable)
|
|
CHECK(hr, S_OK);
|
|
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus;
|
|
|
|
if (S_OK == hr)
|
|
COMPARE(ulStatus, DBPROPSTATUS_OK);
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
if (!fSupported)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fSettable)
|
|
COMPARE(ulStatus, DBPROPSTATUS_BADVALUE);
|
|
else
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a variable_length
|
|
//odtLog << "try to add a non nullable column\n";
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_NULLABLE, VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_REQUIRED,
|
|
DB_NULLID, DBPROPSET_COLUMN, &cPropSet, &cProp);
|
|
rgColumnDesc[i].bScale = 0;
|
|
|
|
// Commenting out the default value
|
|
VariantInit(&defval);
|
|
GetDefaultValue(&rgColumnDesc[i], &defval, pTable);
|
|
if (SettableProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
SetDefaultProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
&defval, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&defval);
|
|
|
|
// it is not necessary that a not nullable column be added
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus;
|
|
if (S_OK == hr)
|
|
COMPARE(ulStatus, DBPROPSTATUS_OK);
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
if (DBPROPSTATUS_OK == rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp + 1].dwStatus)
|
|
{
|
|
if (!fSupported)
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fSettable)
|
|
COMPARE(ulStatus, DBPROPSTATUS_BADVALUE);
|
|
else
|
|
COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
}
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
delete pTable;
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_PRIMARYKEY
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_32()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
DBORDINAL i;
|
|
VARIANT value;
|
|
CCol col;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
BOOL fSettable;
|
|
BOOL fDefaultIsSettable = SettableProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN);
|
|
ULONG cPropSet1, cProp1, cPropSet2, cProp2;
|
|
DBPROPSTATUS dwStatus1, dwStatus2;
|
|
|
|
fSettable = SettableProperty(DBPROP_COL_PRIMARYKEY, DBPROPSET_COLUMN);
|
|
|
|
pTable->CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
DuplicateColumnDesc(&rgColumnDesc[0], 1, &pColumnDesc);
|
|
// this is to prevent SQL Server limiting the size of
|
|
// the index it creates for primary key or unique columns
|
|
SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName)
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"First_column");
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i]) << "\n";
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a PRIMARY KEY column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_PRIMARYKEY, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL, DB_NULLID,
|
|
DBPROPSET_COLUMN, &cPropSet1, &cProp1);
|
|
if (fDefaultIsSettable)
|
|
{
|
|
VariantInit(&value);
|
|
GetDefaultValue(&rgColumnDesc[i], &value, pTable);
|
|
SetDefaultProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
&value, DBPROPOPTIONS_OPTIONAL, DB_NULLID, DBPROPSET_COLUMN, &cPropSet2, &cProp2); // might be not supported
|
|
VariantClear(&value);
|
|
}
|
|
rgColumnDesc[i].bScale = 0;
|
|
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
dwStatus1 = rgColumnDesc[i].rgPropertySets[cPropSet1].rgProperties[cProp1].dwStatus;
|
|
dwStatus2 = rgColumnDesc[i].rgPropertySets[cPropSet2].rgProperties[cProp2].dwStatus;
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
CHECK(hr, DB_S_ERRORSOCCURRED);
|
|
COMPARE(dwStatus1==DBPROPSTATUS_NOTSET || dwStatus2==DBPROPSTATUS_NOTSET, TRUE);
|
|
if (hr==DB_S_ERRORSOCCURRED && dwStatus1==S_OK)
|
|
odtLog << "\tcolumn added as a primary key\n";
|
|
if (hr==DB_S_ERRORSOCCURRED && dwStatus2==S_OK)
|
|
odtLog << "\tcolumn added with the default\n";
|
|
}
|
|
else
|
|
{
|
|
COMPARE(fSettable, TRUE);
|
|
odtLog << "\tcolumn added as a primary key\n";
|
|
COMPARE(dwStatus1, DBPROPSTATUS_OK);
|
|
COMPARE(dwStatus2, DBPROPSTATUS_OK);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a PRIMARY KEY column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_PRIMARYKEY, VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_OPTIONAL, DB_NULLID,
|
|
DBPROPSET_COLUMN, &cPropSet1, &cProp1);
|
|
rgColumnDesc[i].bScale = 0;
|
|
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
dwStatus1 = rgColumnDesc[i].rgPropertySets[cPropSet1].rgProperties[cProp1].dwStatus;
|
|
if (hr != S_OK)
|
|
{
|
|
COMPARE(fSettable, FALSE);
|
|
CHECK(hr, DB_S_ERRORSOCCURRED);
|
|
COMPARE(dwStatus1==DBPROPSTATUS_NOTSET, TRUE);
|
|
}
|
|
else
|
|
{
|
|
COMPARE(fSettable, TRUE);
|
|
odtLog << "\tcolumn was added with primary property off\n";
|
|
COMPARE(dwStatus1, DBPROPSTATUS_OK);
|
|
}
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
SAFE_DELETE(pTable);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_UNIQUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_33()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
DBORDINAL i;
|
|
CCol col;
|
|
HRESULT hr;
|
|
DBPROP *pProp;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
BOOL fSettable = FALSE;
|
|
BOOL fSupported = FALSE;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
DuplicateColumnDesc(&rgColumnDesc[0], 1, &pColumnDesc);
|
|
// this is to prevent SQL Server limiting the size of
|
|
// the index it creates for primary key or unique columns
|
|
SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc->dbcid.uName.pwszName)
|
|
pColumnDesc->dbcid.uName.pwszName = wcsDuplicate(L"First_column");
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
fSupported = SupportedProperty(DBPROP_COL_UNIQUE, DBPROPSET_COLUMN);
|
|
fSettable = SettableProperty(DBPROP_COL_UNIQUE, DBPROPSET_COLUMN);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a UNIQUE column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_UNIQUE, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
rgColumnDesc[i].bScale = 0;
|
|
odtLog << GetColumnTypeName(&rgColumnDesc[i]) << "\n";
|
|
odtLog << "\ttry to add a unique column; \n";
|
|
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
|
|
FindProperty(
|
|
DBPROP_COL_UNIQUE,
|
|
DBPROPSET_COLUMN,
|
|
rgColumnDesc[i].cPropertySets,
|
|
rgColumnDesc[i].rgPropertySets,
|
|
&pProp);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_OK);
|
|
COMPARE(fSupported, TRUE);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
|
|
if (!fSupported)
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fSettable)
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_BADVALUE);
|
|
else
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
|
|
if (!CHECK(m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add the column described by rgColumnDesc[i] to the table
|
|
// and set it as a unique column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
DBPROP_COL_UNIQUE, VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_REQUIRED);
|
|
rgColumnDesc[i].bScale = 0;
|
|
odtLog << "\ttry to add a not unique column; \n";
|
|
|
|
hr = AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], NULL);
|
|
|
|
FindProperty(
|
|
DBPROP_COL_UNIQUE,
|
|
DBPROPSET_COLUMN,
|
|
rgColumnDesc[i].cPropertySets,
|
|
rgColumnDesc[i].rgPropertySets,
|
|
&pProp
|
|
);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_OK);
|
|
COMPARE(fSupported, TRUE);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
|
|
if (!fSupported)
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
else if (fSettable)
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_BADVALUE);
|
|
else
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Duplicate an existing column => DB_E_DUPLCATECOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_34()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column to this maximum length name table
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID),DB_E_DUPLICATECOLUMNID);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_35()
|
|
{
|
|
TBEGIN
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBCOLUMNDESC *newCD = NULL;
|
|
DBCOLUMNDESC *oldCD = NULL;
|
|
DBORDINAL newlen = 0;
|
|
DBORDINAL oldlen = 0;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT vSupportedTxnDDL;
|
|
BOOL fTxnStarted = FALSE;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
// create a table and populate it
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
|
|
// start the transaction
|
|
TESTC_(StartTransaction(pITransactionLocal), S_OK);
|
|
fTxnStarted = TRUE;
|
|
|
|
// try to add a column to this maximum length name table
|
|
if (rgColumnDesc[0].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[0].dbcid.uName.pwszName);
|
|
rgColumnDesc[0].dbcid.uName.pwszName = L"transacted_column";
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->AddColumn(
|
|
&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0],
|
|
&pColumnID), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0], &pColumnID), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
CHECK(m_pITableDefinition->AddColumn(
|
|
&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0],
|
|
&pColumnID), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
// abort retaining
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
CHECK(pITransactionLocal->Abort(NULL, TRUE, FALSE), S_OK);
|
|
// check that it is retaining (another transaction is available)
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
}
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &newCD, &newlen);
|
|
if ( DBPROPVAL_TC_DDL_IGNORE == vSupportedTxnDDL.lVal
|
|
|| DBPROPVAL_TC_DDL_COMMIT == vSupportedTxnDDL.lVal)
|
|
{ // check column was added
|
|
COMPARE(CheckColInfo(oldCD, oldlen, newCD, newlen, &rgColumnDesc[0]), TRUE);
|
|
}
|
|
else
|
|
{ // check column was not added
|
|
COMPARE(AreColEqual(oldCD, oldlen, newCD, newlen), TRUE);
|
|
}
|
|
ReleaseColumnDesc(newCD, newlen);
|
|
newCD = NULL;
|
|
newlen = 0;
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
m_hr = m_pTable->DropTable();
|
|
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
if (rgColumnDesc)
|
|
rgColumnDesc[0].dbcid.uName.pwszName = NULL;
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort without retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_36()
|
|
{
|
|
TBEGIN
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBCOLUMNDESC *newCD = NULL;
|
|
DBCOLUMNDESC *oldCD = NULL;
|
|
DBORDINAL newlen = 0;
|
|
DBORDINAL oldlen = 0;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
// create a table and populate it
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
|
|
// start the transaction
|
|
TESTC_(StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// try to add a column to this maximum length name table
|
|
if (rgColumnDesc[0].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[0].dbcid.uName.pwszName);
|
|
rgColumnDesc[0].dbcid.uName.pwszName = L"transacted_column";
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->AddColumn(
|
|
&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0],
|
|
&pColumnID), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0], &pColumnID), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
CHECK(m_pITableDefinition->AddColumn(
|
|
&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0],
|
|
&pColumnID), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
// abort without retaining
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// abort without retaining
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE),
|
|
SUCCEEDED(m_hr)? XACT_E_NOTRANSACTION : S_OK);
|
|
}
|
|
// check column was not added
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &newCD, &newlen);
|
|
if ( DBPROPVAL_TC_DDL_IGNORE == vSupportedTxnDDL.lVal
|
|
|| DBPROPVAL_TC_DDL_COMMIT == vSupportedTxnDDL.lVal)
|
|
{ // check column was added
|
|
COMPARE(CheckColInfo(oldCD, oldlen, newCD, newlen, &rgColumnDesc[0]), TRUE);
|
|
}
|
|
else
|
|
{ // check column was not added
|
|
COMPARE(AreColEqual(oldCD, oldlen, newCD, newlen), TRUE);
|
|
}
|
|
ReleaseColumnDesc(newCD, newlen);
|
|
newCD = NULL;
|
|
newlen = 0;
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
m_hr = m_pTable->DropTable();
|
|
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
if (rgColumnDesc)
|
|
rgColumnDesc[0].dbcid.uName.pwszName = NULL;
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit with retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_37()
|
|
{
|
|
TBEGIN
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBCOLUMNDESC *newCD = NULL, *oldCD = NULL;
|
|
DBORDINAL newlen = 0, oldlen = 0;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
// create a table and populate it
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
|
|
// start the transaction
|
|
TESTC_(StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// try to add a column to this maximum length name table
|
|
if (rgColumnDesc[0].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
rgColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"transacted_column");
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->AddColumn(
|
|
&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0],
|
|
&pColumnID), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0], &pColumnID), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
CHECK(m_pITableDefinition->AddColumn(
|
|
&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0],
|
|
&pColumnID), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
// commit with retaining
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
CHECK(pITransactionLocal->Commit(TRUE, 0, 0), S_OK); //XACTTC_SYNC, 0), S_OK))
|
|
//check the commit with retaining
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
}
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &newCD, &newlen);
|
|
if (DBPROPVAL_TC_DML == vSupportedTxnDDL.lVal)
|
|
{ // check column was not added
|
|
COMPARE(AreColEqual(oldCD, oldlen, newCD, newlen), TRUE);
|
|
}
|
|
else
|
|
{ // check column was added
|
|
COMPARE(CheckColInfo(oldCD, oldlen, newCD, newlen, &rgColumnDesc[0]), TRUE);
|
|
}
|
|
ReleaseColumnDesc(newCD, newlen);
|
|
newCD = NULL;
|
|
newlen = 0;
|
|
|
|
CLEANUP:
|
|
if (rgColumnDesc)
|
|
rgColumnDesc[0].dbcid.uName.pwszName = NULL;
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
m_hr = m_pTable->DropTable();
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(38)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit without retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_38()
|
|
{
|
|
TBEGIN
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBCOLUMNDESC *newCD = NULL, *oldCD = NULL;
|
|
DBORDINAL newlen = 0, oldlen = 0;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT vSupportedTxnDDL;
|
|
BOOL fDDL_LOCK = FALSE;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
// create a table and populate it
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
// start the transaction
|
|
TESTC_(StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// try to add a column to this maximum length name table
|
|
if (rgColumnDesc[0].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[0].dbcid.uName.pwszName);
|
|
rgColumnDesc[0].dbcid.uName.pwszName = L"transacted_column";
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->AddColumn(
|
|
&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0],
|
|
&pColumnID), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0], &pColumnID), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
CHECK(m_pITableDefinition->AddColumn(
|
|
&m_pTable->GetTableID(),
|
|
&rgColumnDesc[0],
|
|
&pColumnID), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// commit without retaining
|
|
CHECK(m_hr = pITransactionLocal->Commit(FALSE, XACTTC_SYNC, 0), S_OK);
|
|
//check the commit without retaining
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE), FAILED(m_hr)? S_OK: XACT_E_NOTRANSACTION);
|
|
}
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &newCD, &newlen);
|
|
if (DBPROPVAL_TC_DML == vSupportedTxnDDL.lVal)
|
|
{ // check column was not added
|
|
COMPARE(AreColEqual(oldCD, oldlen, newCD, newlen), TRUE);
|
|
}
|
|
else
|
|
{ // check column was added
|
|
COMPARE(CheckColInfo(oldCD, oldlen, newCD, newlen, &rgColumnDesc[0]), TRUE);
|
|
}
|
|
ReleaseColumnDesc(newCD, newlen);
|
|
|
|
CLEANUP:
|
|
if (rgColumnDesc)
|
|
rgColumnDesc[0].dbcid.uName.pwszName = NULL;
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
m_hr = m_pTable->DropTable();
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(39)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add a column for each provider type in an empty table => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_39()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
WCHAR *pwszName;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
pwszName = rgColumnDesc[0].dbcid.uName.pwszName;
|
|
m_pTable->SetColumnDesc(rgColumnDesc, 1);
|
|
|
|
// for each type in DBCOLUMNDESC, add a column with maximum column size
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszName;
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
// try to add a column from rgColumnDesc[i]
|
|
odtLog << "column name:" << rgColumnDesc[i].dbcid.uName.pwszName <<
|
|
" column type:" << rgColumnDesc[i].pwszTypeName << "\n";
|
|
|
|
rgColumnDesc[0].dbcid.uName.pwszName = L"Initial_column";
|
|
// create a table with a single column, equal to the first one in the row
|
|
if (!CHECK(m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszName;
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], &pColumnID), S_OK);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
}
|
|
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszName;
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(40)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add a column to a table created with a SQL command => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_40()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
BOOL fTableCreation;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
IDBCreateCommand *pIDBCreateCommand = NULL;
|
|
|
|
// check wheter the commands are supported
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_IDBCreateCommand,
|
|
SESSION_INTERFACE, (IUnknown**)&pIDBCreateCommand));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
// set order for table creation
|
|
fTableCreation = GetModInfo()->UseITableDefinition(FALSE);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column to this maximum length name table
|
|
SAFE_FREE(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName);
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = wcsDuplicate(L"new_column");
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1], &pColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
m_pTable->DropTable();
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
GetModInfo()->UseITableDefinition(fTableCreation);
|
|
ReleaseDBID(pColumnID);
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(41)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop all the column of a table (via SQL stmt) and then try to add a column => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_41()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
BOOL fTableCreation;
|
|
DB_LORDINAL rgCol[1] = {1};
|
|
DB_LORDINAL *prgCol = rgCol;
|
|
DBORDINAL nCol = 1;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 1;
|
|
IDBCreateCommand *pIDBCreateCommand = NULL;
|
|
|
|
// check whether commands are supported
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_IDBCreateCommand,
|
|
SESSION_INTERFACE, (IUnknown**)&pIDBCreateCommand));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
// create a table with a single column, using a SQL command
|
|
fTableCreation = GetModInfo()->UseITableDefinition(FALSE);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// drop the only existing column from the table
|
|
TESTC_PROVIDER(S_OK == m_pTable->ExecuteCommand(
|
|
ALTER_TABLE_DROP_COLUMN,
|
|
IID_NULL,
|
|
NULL, // the table name will be the implicit one
|
|
NULL, // don't return the command statement
|
|
&nCol,
|
|
(DB_LORDINAL**)&prgCol,
|
|
EXECUTE_IFNOERROR // execute the command
|
|
));
|
|
|
|
// try to add a column to this table
|
|
SAFE_FREE(rgColumnDesc[0].dbcid.uName.pwszName);
|
|
rgColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"new_column");
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[0], &pColumnID), S_OK);
|
|
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
|
|
CLEANUP:
|
|
GetModInfo()->UseITableDefinition(fTableCreation);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(42)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Non NULL pTypeInfo in DBCOLUMNDESC => DB_E_BADTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_42()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a NULL value for name pointer
|
|
rgColumnDesc[cColumnDesc-1].pTypeInfo = (ITypeInfo*)m_pITableDefinition;
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID), DB_E_BADTYPE);
|
|
|
|
CLEANUP:
|
|
m_pTable->DropTable();
|
|
rgColumnDesc[cColumnDesc-1].pTypeInfo = NULL;
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(43)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Missmatch between wType and pwszTypeName => DB_E_BADTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_43()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to add a column with a NULL value for name pointer
|
|
for (i=0; i<cColumnDesc-1 && rgColumnDesc[i].wType == rgColumnDesc[cColumnDesc-1].wType; i++);
|
|
TESTC_PROVIDER(i < cColumnDesc-2);
|
|
|
|
if (rgColumnDesc[cColumnDesc-1].pwszTypeName)
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].pwszTypeName);
|
|
rgColumnDesc[cColumnDesc-1].pwszTypeName = wcsDuplicate(rgColumnDesc[i].pwszTypeName);
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID), DB_E_BADTYPE);
|
|
|
|
CLEANUP:
|
|
m_pTable->DropTable();
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(44)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add a not nullable column and try to insert a null value for it
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_44()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBID *pColumnID = NULL;
|
|
DBORDINAL i;
|
|
DBORDINAL nCol[1];
|
|
CCol col;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
BOOL fFound;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT defval;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
if (!SettableProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN) && 2 > m_cColumnDesc)
|
|
{
|
|
TESTB = TEST_SKIPPED;
|
|
goto CLEANUP1;
|
|
}
|
|
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
// use all the types from the not nullable one (exclusive)
|
|
m_pTable->SetColumnDesc(&rgColumnDesc[1], cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(10, 0), S_OK);
|
|
|
|
if (rgColumnDesc[0].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[0].dbcid.uName.pwszName);
|
|
rgColumnDesc[0].dbcid.uName.pwszName = L"NewColumn";
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets, DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_REQUIRED, DB_NULLID, DBPROPSET_COLUMN);
|
|
if (SettableProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
{
|
|
VariantInit(&defval);
|
|
GetDefaultValue(&rgColumnDesc[0], &defval);
|
|
SetDefaultProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
&defval, DBPROPOPTIONS_OPTIONAL); // might be not supported
|
|
VariantClear(&defval);
|
|
}
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[0], &pColumnID), S_OK);
|
|
// must update info about table in m_pTable
|
|
m_pTable->GetTableColumnInfo(&m_pTable->GetTableID());
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
DBKIND_NAME != m_pTable->GetTableID().eKind? m_pTable->GetTableID().uName.pwszName: NULL);
|
|
|
|
for (i=0, fFound=FALSE; !fFound && i<m_pTable->CountColumnsOnTable(); i++)
|
|
{
|
|
col = m_pTable->GetColInfoForUpdate(i+1);
|
|
if (CompareDBID(rgColumnDesc[0].dbcid, *col.GetColID(), m_pIDBInitialize))
|
|
{
|
|
nCol[0] = col.GetColNum();
|
|
fFound = TRUE;
|
|
}
|
|
}
|
|
TESTC(fFound);
|
|
TEST2C_(hr = m_pIOpenRowset->OpenRowset(NULL, &m_pTable->GetTableID(), NULL,
|
|
IID_IRowsetChange, 0, NULL, (IUnknown**)&pIRowsetChange), S_OK, E_NOINTERFACE);
|
|
TESTC_PROVIDER(S_OK == hr);
|
|
|
|
// try to insert a null value in a not null column
|
|
hr = Insert(0, pIRowsetChange, NUMELEM(nCol), nCol);
|
|
|
|
if (DB_E_NOTSUPPORTED != hr)
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
m_pTable->SetColumnDesc(NULL);
|
|
CLEANUP1:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
if (rgColumnDesc)
|
|
rgColumnDesc[0].dbcid.uName.pwszName = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(45)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add a column on a view
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_45()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBID *pColumnID = NULL;
|
|
LPWSTR pwszViewName = L"VirTab";
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
IDBCreateCommand *pIDBCreateCommand = NULL;
|
|
|
|
// check whether commands are supported
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_IDBCreateCommand,
|
|
SESSION_INTERFACE, (IUnknown**)&pIDBCreateCommand));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(10, 1), S_OK);
|
|
|
|
m_pTable->SetViewName(pwszViewName);
|
|
if ( !CHECK(m_pTable->ExecuteCommand(
|
|
CREATE_VIEW,
|
|
IID_NULL,
|
|
pwszViewName, // the table name will be the implicit one
|
|
NULL, // don't return the command statement
|
|
0,
|
|
NULL,
|
|
EXECUTE_IFNOERROR // execute the command
|
|
), S_OK)
|
|
)
|
|
{
|
|
odtLog << "\tA view on the table could not be created\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// try to add a column to this maximum length name table
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName);
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = wcsDuplicate(L"new_column");
|
|
// prepare the DBID to reflect the view
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = pwszViewName;
|
|
TEST3C_(AddColumnAndCheck(&TableID, &rgColumnDesc[cColumnDesc-1], &pColumnID),
|
|
E_FAIL, DB_E_NOTABLE, DB_SEC_E_PERMISSIONDENIED)
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
ReleaseDBID(pColumnID);
|
|
// drop the view!
|
|
if (m_pTable->GetTableName())
|
|
m_pTable->ExecuteCommand(
|
|
DROP_VIEW,
|
|
IID_NULL,
|
|
pwszViewName, // the table name will be the implicit one
|
|
NULL, // don't return the command statement
|
|
0,
|
|
NULL,
|
|
EXECUTE_IFNOERROR // execute the command
|
|
);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(46)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc eKind != DBKIND_NAME for a column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_46()
|
|
// try to use all the DBKIND values
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(10, 0), S_OK);
|
|
|
|
// try to add a column with different DBKIND values
|
|
odtLog << "Add DBKIND_GUID_NAME column\n";
|
|
if (rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName)
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName);
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_GUID_NAME;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uGuid.guid = guidModule;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = L"DBKIND_GUID_NAME";
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
|
|
odtLog << "Add DBKIND_GUID_PROPID column\n";
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_GUID_PROPID;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.ulPropid = 0;
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
|
|
odtLog << "Add DBKIND_NAME column\n";
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = L"DBKIND_NAME";
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), S_OK);
|
|
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
|
|
odtLog << "Add DBKIND_PGUID_NAME column\n";
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_PGUID_NAME;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = L"DBKIND_PGUID_NAME";
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uGuid.pguid = &guidModule;
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
|
|
odtLog << "Add DBKIND_PGUID_PROPID column\n";
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_PGUID_PROPID;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.ulPropid = 0;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uGuid.pguid = &guidModule;
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
|
|
odtLog << "Add DBKIND_PROPID column\n";
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_PROPID;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.ulPropid = 0;
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
|
|
odtLog << "Add DBKIND_GUID column\n";
|
|
rgColumnDesc[cColumnDesc-1].dbcid.eKind = DBKIND_GUID;
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.ulPropid = 0;
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), DB_E_BADCOLUMNID);
|
|
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
rgColumnDesc[cColumnDesc-1].dbcid.uName.pwszName = NULL;
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Thread funtion for TCAddColumn
|
|
//---------------------------------------------------------------------
|
|
unsigned TCAddColumn::MyThreadProc(ULONG i)
|
|
{
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
HRESULT hr;
|
|
|
|
if (i>= nThreads)
|
|
return 0;
|
|
DuplicateColumnDesc(m_rgColumnDesc, 1, &pColumnDesc);
|
|
ReleaseDBID(&pColumnDesc->dbcid, FALSE);
|
|
pColumnDesc->dbcid.eKind = DBKIND_NAME;
|
|
pColumnDesc->dbcid.uName.pwszName = m_rgName[i];
|
|
Sleep(0); // switch the context
|
|
|
|
|
|
hr = m_pITableDefinition->AddColumn(&m_pTable->GetTableID(), pColumnDesc, NULL);
|
|
Sleep(0); // switch the context
|
|
|
|
pColumnDesc->dbcid.uName.pwszName = NULL;
|
|
ReleaseColumnDesc(pColumnDesc, 1);
|
|
m_rgResult[i] = hr;
|
|
return 1;
|
|
} //TCAddColumn::MyThreadProc
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(47)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc threads with different column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_47()
|
|
{
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
BOOL fTestResult = TEST_FAIL;
|
|
ULONG i;
|
|
LPWSTR pwszBaseName = NULL;
|
|
WCHAR number[3];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
ULONG cColumnDesc = 1;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
// create n names and init the results
|
|
for (i=0; i<nThreads; i++)
|
|
m_rgName[i] = NULL;
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
pwszBaseName = m_pTable->GetTableName();
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
m_rgName[i] = (WCHAR*)PROVIDER_ALLOC((3+wcslen(pwszBaseName))*sizeof(WCHAR));
|
|
ASSERT(m_rgName[i]);
|
|
wcscpy(m_rgName[i], pwszBaseName);
|
|
swprintf(number, L"%02d", i);
|
|
wcscat(m_rgName[i], number);
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// creates a table, build rgColumnDesc by it
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
TESTC_(m_rgResult[i], S_OK);
|
|
fTestResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
DropTableAndCheck(&m_pTable->GetTableID());
|
|
for (i=0; i<nThreads; i++)
|
|
PROVIDER_FREE(m_rgName[i]);
|
|
return fTestResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(48)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc threads on the same column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_48()
|
|
{
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
BOOL fTestResult = TEST_FAIL;
|
|
ULONG i, nS_OK, nDB_E_DUPLICATECOLUMNID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
ULONG cColumnDesc = 1;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
m_rgName[i] = L"someOtherColumn";
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// creates a table, build rgColumnDesc by it
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=nS_OK=nDB_E_DUPLICATECOLUMNID=0; i<nThreads; i++)
|
|
{
|
|
if (m_rgResult[i] == S_OK)
|
|
nS_OK++;
|
|
else if (CHECK(m_rgResult[i], DB_E_DUPLICATECOLUMNID))
|
|
nDB_E_DUPLICATECOLUMNID++;
|
|
else
|
|
goto CLEANUP;
|
|
}
|
|
TESTC(nS_OK== 1 && nDB_E_DUPLICATECOLUMNID == nThreads-1);
|
|
fTestResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
DropTableAndCheck(&m_pTable->GetTableID());
|
|
return fTestResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(49)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc add columns of alll known wType => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_49()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *pColumnDesc = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
DuplicateColumnDesc(&rgColumnDesc[0], 1, &pColumnDesc);
|
|
PROVIDER_FREE(pColumnDesc[0].dbcid.uName.pwszName);
|
|
pColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"ColoanaInitiala");
|
|
m_pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
// create a table with a single column, equal to the first one in the row
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
continue;
|
|
|
|
// try to add a column from rgColumnDesc[i] with a NULL name and a valid wType
|
|
PROVIDER_FREE(rgColumnDesc[i].pwszTypeName);
|
|
odtLog << "column name: " << rgColumnDesc[i].dbcid.uName.pwszName << "\n";
|
|
|
|
CHECK(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i], &pColumnID), S_OK);
|
|
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(pColumnID);
|
|
pColumnID = NULL;
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(50)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Fully Qualified table name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_50()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBID BaseTableID;
|
|
WCHAR *pwszQualTableName = NULL;
|
|
WCHAR *pwszCatalogName = NULL;
|
|
WCHAR *pwszSchemaName = NULL;
|
|
WCHAR *pwszTableName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
// create a regular table
|
|
TESTC(NULL != m_pTable);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
pwszTableName = m_pTable->GetTableName();
|
|
TableID.eKind = DBKIND_NAME;
|
|
|
|
BaseTableID.eKind = DBKIND_NAME;
|
|
BaseTableID.uName.pwszName = pwszTableName;
|
|
|
|
TESTC(GetCatalogSchemaNames(pwszTableName, &pwszCatalogName, &pwszSchemaName));
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(m_pTable->GetQualifiedName(pwszCatalogName, pwszSchemaName, pwszTableName, &pwszQualTableName),S_OK);
|
|
TableID.uName.pwszName = pwszQualTableName;
|
|
|
|
m_pTable->BuildColumnDescs(&rgColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc=m_pTable->CountColumnsOnTable());
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE);
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"AltaColoana");
|
|
|
|
TESTC_(AddColumnAndCheck(&TableID, &rgColumnDesc[0], NULL, NULL, &BaseTableID), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
SAFE_FREE(pwszQualTableName);
|
|
m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(51)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Quoted Table Name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_51()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
TESTC(NULL != m_pTable);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
m_pTable->GetQuotedName(m_pTable->GetTableName(), &TableID.uName.pwszName);
|
|
|
|
m_pTable->BuildColumnDescs(&rgColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc=m_pTable->CountColumnsOnTable());
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE);
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"AltaColoana");
|
|
|
|
TESTC_(AddColumnAndCheck(&TableID, &rgColumnDesc[0], NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(&TableID, FALSE);
|
|
m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(52)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc == NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_52()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), NULL, &pColumnID), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(53)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cPropertySets != 0 and rgPropertySets == NULL in pColumnDesc => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_53()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(10, 0), S_OK);
|
|
// try to add a column with a bad wType
|
|
rgColumnDesc[cColumnDesc-1].cPropertySets = (BYTE)(rand()%255+1);
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets = NULL;
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(pColumnID);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
// restore the proper number of properties for the column
|
|
rgColumnDesc[cColumnDesc-1].cPropertySets = 0;
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(54)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cPropertySets == 0 and rgPropertySets != NULL in pColumnDesc => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_54()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPSET rgPropertySets[1];
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(10, 0), S_OK);
|
|
// try to add a column with a bad wType
|
|
rgColumnDesc[cColumnDesc-1].cPropertySets = 0;
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets = rgPropertySets;
|
|
memset(rgPropertySets, 0, sizeof(DBPROPSET));
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets = NULL;
|
|
ReleaseDBID(pColumnID);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
// restore the property set array
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets = NULL;
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(55)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cProperties == 0 and rgProperties != NULL in pColumnDesc's propset => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_55()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPSET rgPropertySets[1];
|
|
DBPROP rgProperties[1];
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(10, 0), S_OK);
|
|
// try to add a column with a bad wType
|
|
rgColumnDesc[cColumnDesc-1].cPropertySets = NUMELEM(rgPropertySets);
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets = rgPropertySets;
|
|
memset(rgPropertySets, 0, sizeof(DBPROPSET));
|
|
rgPropertySets[0].guidPropertySet = DBPROPSET_COLUMN;
|
|
rgPropertySets[0].cProperties = 0;
|
|
rgPropertySets[0].rgProperties = rgProperties;
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets = NULL;
|
|
ReleaseDBID(pColumnID);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
// restore the prop array
|
|
rgPropertySets[0].rgProperties = NULL;
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(56)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cProperties != 0 and rgProperties == NULL in pColumnDesc's propset => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_56()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPSET rgPropertySets[1];
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(10, 0), S_OK);
|
|
|
|
// built the property set array
|
|
rgColumnDesc[cColumnDesc-1].cPropertySets = NUMELEM(rgPropertySets);
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets = rgPropertySets;
|
|
memset(rgPropertySets, 0, sizeof(DBPROPSET));
|
|
rgPropertySets[0].guidPropertySet = DBPROPSET_COLUMN;
|
|
rgPropertySets[0].cProperties = (BYTE)(rand()%255+1);
|
|
rgPropertySets[0].rgProperties = NULL;
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
rgColumnDesc[cColumnDesc-1].rgPropertySets = NULL;
|
|
ReleaseDBID(pColumnID);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
// restore the prop counter
|
|
rgPropertySets[0].cProperties = 0;
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(57)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pclsid not null
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_57()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
HRESULT hr;
|
|
POSITION pos;
|
|
CCol col;
|
|
BOOL fOleSupported = FALSE;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_pTable->CreateTable(10, 0), S_OK);
|
|
|
|
// set pclsid to IID_NULL
|
|
rgColumnDesc[cColumnDesc-1].pclsid = (GUID*)&IID_NULL;
|
|
|
|
// check that pclsid is ignored
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(),
|
|
&rgColumnDesc[cColumnDesc-1], &pColumnID),S_OK);
|
|
|
|
TESTC_(m_pTable->DropTable(), S_OK);
|
|
TESTC_(m_pTable->CreateTable(10, 0), S_OK);
|
|
|
|
// check DBTYPE_IUNKNOWN is supported
|
|
for (pos = m_ColList.GetHeadPosition(); pos; )
|
|
{
|
|
col = m_ColList.GetNext(pos);
|
|
if (DBTYPE_IUNKNOWN == col.GetProviderType())
|
|
{
|
|
fOleSupported = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check whether a DBTYPE_IUNKNOWN column can be created in the table
|
|
rgColumnDesc[cColumnDesc-1].wType = DBTYPE_IUNKNOWN;
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].pwszTypeName);
|
|
if (fOleSupported)
|
|
rgColumnDesc[cColumnDesc-1].pwszTypeName = wcsDuplicate(col.GetProviderTypeName());
|
|
hr = fOleSupported ? S_OK : DB_E_BADTYPE;
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID), hr);
|
|
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(pColumnID);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(58)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL pwszTypeName => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddColumn::Variation_58()
|
|
{
|
|
TBEGIN
|
|
DBID *pColumnID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc-1);
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(10, 0), S_OK);
|
|
// try to add a column with a bad wType
|
|
PROVIDER_FREE(rgColumnDesc[cColumnDesc-1].pwszTypeName);
|
|
rgColumnDesc[cColumnDesc-1].pwszTypeName = NULL;
|
|
|
|
TESTC_(AddColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumnDesc-1],
|
|
&pColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
m_pTable->SetNoOfColumnDesc(cColumnDesc);
|
|
ReleaseDBID(pColumnID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddColumn::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCDropColumn)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCDropColumn - Test case for dropping columns
|
|
//| Created: 09/11/97
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCDropColumn::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
//----------------------------------------------------------------------
|
|
//
|
|
// @cmember Check whether the 2 list of columns are identical,
|
|
// excepting column n
|
|
//----------------------------------------------------------------------
|
|
BOOL TCDropColumn::IsColumnDifferention(
|
|
DBCOLUMNDESC *newlist,
|
|
ULONG newlen,
|
|
DBCOLUMNDESC *oldlist,
|
|
ULONG oldlen,
|
|
ULONG n
|
|
)
|
|
{
|
|
ULONG nNewCol;
|
|
ULONG nOldCol;
|
|
|
|
if (!newlist || !oldlist)
|
|
return oldlist == newlist;
|
|
if (newlen != oldlen - 1)
|
|
return FALSE;
|
|
|
|
// it is assumed that the columns should be identical up to column n
|
|
// the new column n will be the oldcolumn n+1, the new column n+1
|
|
// should be identical to the old column n+2, etc
|
|
for (nNewCol = nOldCol = 0; nNewCol < newlen; nNewCol++)
|
|
{
|
|
if (nNewCol == n)
|
|
nOldCol++;
|
|
if (!CompareDBID(newlist[nNewCol].dbcid, oldlist[nOldCol++].dbcid, m_pIDBInitialize))
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
} //TCDropColumn::IsColumnDifferention
|
|
//----------------------------------------------------------------------
|
|
//
|
|
// @cmember Check whether the 2 list of columns are identical
|
|
//----------------------------------------------------------------------
|
|
BOOL TCDropColumn::ListEqual(DBCOLUMNDESC *newlist, ULONG newlen, DBCOLUMNDESC *oldlist, ULONG oldlen)
|
|
{
|
|
ULONG i;
|
|
|
|
if (!newlist || !oldlist)
|
|
return newlist == oldlist;
|
|
if (newlen != oldlen)
|
|
return FALSE;
|
|
for (i=0; i<newlen; i++)
|
|
if (!CompareDBID(newlist[i].dbcid, oldlist[i].dbcid, m_pIDBInitialize))
|
|
return FALSE;
|
|
return TRUE;
|
|
} //TCDropColumn::ListEqual
|
|
*/
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_1()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = L"Gateway2001";
|
|
|
|
TESTC_(DropColumnAndCheck(NULL, &ColumnID), E_INVALIDARG);
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnID in NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pTableID is DB_NULLID => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_3()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
DBID TableID = DB_NULLID;
|
|
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = L"Gateway2001";
|
|
|
|
TESTC_(DropColumnAndCheck(&TableID, &ColumnID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pColumnID is DB_NULLID => DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_4()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
|
|
memset(&ColumnID, 0, sizeof(DBID));
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length table name => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_5()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
DBID TableID;
|
|
DBORDINAL n, cColumns;
|
|
DBCOLUMNINFO *rgColInfo = NULL;
|
|
LPWSTR pwszTableName;
|
|
OLECHAR *pStringBuffer = NULL;
|
|
DBORDINAL ulOrdinal = 0;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = pwszTableName = BuildValidName(m_cMaxTableName, m_pTable->GetTableName());
|
|
PRVTRACE(L"** TCDropColumn::Variation_5(): create a table with max table name: %s, %d\n",
|
|
pwszTableName, n=wcslen(pwszTableName));
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0, pwszTableName), S_OK);
|
|
|
|
GetColumnInfo(&TableID, &cColumns, &rgColInfo, &pStringBuffer);
|
|
TESTC(0 < cColumns);
|
|
// check if the first column is bookmark or not
|
|
if (0 == rgColInfo[0].iOrdinal)
|
|
ulOrdinal = 1;
|
|
|
|
TESTC(ulOrdinal < cColumns);
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = rgColInfo[ulOrdinal].pwszName;
|
|
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_hr = m_pTable->DropTable(), S_OK);
|
|
PROVIDER_FREE(pStringBuffer);
|
|
PROVIDER_FREE(rgColInfo);
|
|
PROVIDER_FREE(pwszTableName);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 1-char-too long table name => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_6()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
DBID ColumnID;
|
|
DBID TableID;
|
|
DBCOLUMNDESC *oldCD=NULL;
|
|
DBORDINAL oldlen;
|
|
LPWSTR pwszTableName;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = BuildValidName(m_cMaxTableName+1, m_pTable->GetTableName());
|
|
pwszTableName = BuildValidName(m_cMaxTableName, m_pTable->GetTableName());
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0, pwszTableName), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = wcsDuplicate(oldCD[0].dbcid.uName.pwszName);
|
|
|
|
TESTC_(DropColumnAndCheck(&TableID, &ColumnID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
ReleaseDBID(&TableID, FALSE);
|
|
PROVIDER_FREE(pwszTableName);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pTableID contains a NULL table name => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_7()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
DBID TableID;
|
|
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = L"Gateway2001";
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
|
|
TESTC_(DropColumnAndCheck(&TableID, &ColumnID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pTableID contains an invalid name => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_8()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
DBID TableID;
|
|
size_t n;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
n = min(wcslen(m_pwszInvalidTableChars)+wcslen(m_pTable->GetTableName()), m_cMaxTableName);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = BuildInvalidName(n, m_pTable->GetTableName(), m_pwszInvalidTableChars);
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = L"foca";
|
|
|
|
TESTC_(DropColumnAndCheck(&TableID, &ColumnID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length for a column name => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
LPWSTR pwszColumnName;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->MakeTableName(NULL);
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = pwszColumnName = BuildValidName(m_cMaxColName, L"aaabcdef");
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE);
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszColumnName;
|
|
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 1-char-too-long column name => DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_10()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
LPWSTR pwszColumnName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = pwszColumnName = BuildValidName(m_cMaxColName, L"aaabcdef");
|
|
ColumnID.uName.pwszName = BuildValidName(m_cMaxColName+1, m_pTable->GetTableName());
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE);
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszColumnName;
|
|
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
PROVIDER_FREE(ColumnID.uName.pwszName);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pColumnID contains a NULL column name pointer => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_11()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
|
|
// create a table, which contains a maximum size table length
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = NULL;
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pColumnID contains an invalid column name => E_INVALID ARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_12()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
LPWSTR pwszColumnName;
|
|
size_t n;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
m_pTable->MakeTableName(NULL);
|
|
n = min(wcslen(m_pTable->GetTableName())+wcslen(m_pwszInvalidColChars), m_cMaxColName);
|
|
pwszColumnName = BuildInvalidName(n, m_pTable->GetTableName(), m_pwszInvalidColChars);
|
|
// create a table, which contains a maximum size table length
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = pwszColumnName;
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
PROVIDER_FREE(pwszColumnName);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop all the columns of a table => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_13()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBID ColumnID;
|
|
DBORDINAL n, cColumns;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
//GetColumnInfo(&m_pTable->GetTableID(), &cColumns, &rgColInfo, &pStringBuffer);
|
|
TESTC(GetColumnDescOnTable(&m_pTable->GetTableID(), &rgColumnDesc, &cColumns));
|
|
// check for bookmarks
|
|
n = 0;
|
|
for (; n < cColumns-1; n++)
|
|
{
|
|
// drop column i
|
|
//DuplicateDBID(rgColInfo[n].columnid, &ColumnID);
|
|
DuplicateDBID(rgColumnDesc[n].dbcid, &ColumnID);
|
|
if ( !CHECK(hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID),
|
|
S_OK))
|
|
{
|
|
if (DBKIND_NAME == rgColumnDesc[n].dbcid.eKind)
|
|
odtLog << "cannot drop column " << rgColumnDesc[n].dbcid.uName.pwszName << "!\n";
|
|
}
|
|
else if (DBKIND_NAME == rgColumnDesc[n].dbcid.eKind)
|
|
odtLog << "Column "<< rgColumnDesc[n].dbcid.uName.pwszName << " was successfully dropped\n";
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
}
|
|
// try to drop the last column
|
|
DuplicateDBID(rgColumnDesc[cColumns-1].dbcid, &ColumnID);
|
|
hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (FAILED(hr))
|
|
{
|
|
if (DBKIND_NAME == rgColumnDesc[cColumns-1].dbcid.eKind)
|
|
odtLog << "cannot drop column " << rgColumnDesc[cColumns-1].dbcid.uName.pwszName << " (the last one)!\n";
|
|
}
|
|
else if (DBKIND_NAME == rgColumnDesc[cColumns-1].dbcid.eKind)
|
|
odtLog << "Column "<< rgColumnDesc[cColumns-1].dbcid.uName.pwszName << " (the last column) was successfully dropped\n";
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
//PROVIDER_FREE(rgColInfo);
|
|
//PROVIDER_FREE(pStringBuffer);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumns, TRUE);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Try to delete an inexistent column => DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_14()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = L"inexistentColumn";
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table in use => DB_E_TABLEINUSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_15()
|
|
{
|
|
TBEGIN
|
|
IRowset *pIRowset=NULL;
|
|
CCol col;
|
|
|
|
m_pTable->SetRowset((IUnknown**)&pIRowset);
|
|
m_pTable->SetRIID((struct _GUID*)&IID_IRowset);
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
DBKIND_NAME != m_pTable->GetTableID().eKind? m_pTable->GetTableID().uName.pwszName: NULL);
|
|
|
|
col = m_pTable->GetColInfoForUpdate(1);
|
|
TEST2C_(m_hr = DropColumnAndCheck(&m_pTable->GetTableID(),
|
|
col.GetColID()), S_OK, DB_E_TABLEINUSE);
|
|
|
|
odtLog << ((S_OK == m_hr)? "column was dropped\n": "column has been preserved\n");
|
|
|
|
CLEANUP:
|
|
m_pTable->SetRowset(NULL);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Valid name of an inexistent table => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_16()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID, TableID;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
DuplicateDBID(m_rgColumnDesc[0].dbcid, &ColumnID);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
TEST2C_(m_hr = DropColumnAndCheck(&TableID, &ColumnID), DB_E_NOTABLE, g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN);
|
|
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort with retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_17()
|
|
{
|
|
TBEGIN
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBCOLUMNDESC *newCD = NULL, *oldCD = NULL;
|
|
DBORDINAL newlen = 0, oldlen = 0;
|
|
CCol col;
|
|
DBORDINAL nCol;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
// create a table
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
|
|
// start the transaction
|
|
TESTC_(m_hr = StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// try to drop a column from table
|
|
nCol = (ULONG)rand()%m_pTable->CountColumnsOnTable()+1;
|
|
col = m_pTable->GetColInfoForUpdate(nCol);
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_pITableDefinition->DropColumn(&m_pTable->GetTableID(),
|
|
col.GetColID()), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
CHECK(m_pITableDefinition->DropColumn(&m_pTable->GetTableID(),
|
|
col.GetColID()), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
// abort retaining
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
CHECK(pITransactionLocal->Abort(NULL, TRUE, FALSE), S_OK);
|
|
//check the retaining propriety
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
}
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &newCD, &newlen);
|
|
if ( DBPROPVAL_TC_DDL_IGNORE == vSupportedTxnDDL.lVal
|
|
|| DBPROPVAL_TC_DDL_COMMIT == vSupportedTxnDDL.lVal)
|
|
{ // check column was dropped
|
|
COMPARE(CheckColInfo(newCD, newlen, oldCD, oldlen, &oldCD[nCol-1]), TRUE);
|
|
}
|
|
else
|
|
{ // check column was not dropped
|
|
COMPARE(AreColEqual(oldCD, oldlen, newCD, newlen), TRUE);
|
|
}
|
|
ReleaseColumnDesc(newCD, newlen);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
m_hr = m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort without retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_18()
|
|
{
|
|
TBEGIN
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBCOLUMNDESC *newCD = NULL, *oldCD = NULL;
|
|
DBORDINAL newlen = 0, oldlen = 0;
|
|
CCol col;
|
|
DBORDINAL nCol;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
// create a table
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
|
|
// start the transaction
|
|
TESTC_(m_hr = StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// try to drop a column from table
|
|
nCol = (DBORDINAL)rand()%m_pTable->CountColumnsOnTable()+1;
|
|
col = m_pTable->GetColInfoForUpdate(nCol);
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_pITableDefinition->DropColumn(&m_pTable->GetTableID(),
|
|
col.GetColID()), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
CHECK(m_pITableDefinition->DropColumn(&m_pTable->GetTableID(),
|
|
col.GetColID()), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// abort non retaining
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
//check the non-retaining propriety
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE),
|
|
SUCCEEDED(m_hr)? XACT_E_NOTRANSACTION: S_OK);
|
|
}
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &newCD, &newlen);
|
|
if ( DBPROPVAL_TC_DDL_IGNORE == vSupportedTxnDDL.lVal
|
|
|| DBPROPVAL_TC_DDL_COMMIT == vSupportedTxnDDL.lVal)
|
|
{ // check column was dropped
|
|
COMPARE(CheckColInfo(newCD, newlen, oldCD, oldlen, &oldCD[nCol-1]), TRUE);
|
|
}
|
|
else
|
|
{ // check column was not dropped
|
|
COMPARE(AreColEqual(oldCD, oldlen, newCD, newlen), TRUE);
|
|
}
|
|
ReleaseColumnDesc(newCD, newlen);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
m_hr = m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit with retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_19()
|
|
{
|
|
TBEGIN
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBCOLUMNDESC *newCD = NULL, *oldCD = NULL;
|
|
DBORDINAL newlen = 0, oldlen = 0;
|
|
CCol col;
|
|
DBORDINAL nCol;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
// create a table
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
|
|
// start the transaction
|
|
TESTC_(m_hr = StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// try to drop a column from table
|
|
nCol = (ULONG)rand()%m_pTable->CountColumnsOnTable()+1;
|
|
col = m_pTable->GetColInfoForUpdate(nCol);
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_pITableDefinition->DropColumn(&m_pTable->GetTableID(),
|
|
col.GetColID()), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
CHECK(m_pITableDefinition->DropColumn(&m_pTable->GetTableID(),
|
|
col.GetColID()), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
// abort retaining
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// commit retaining
|
|
CHECK(pITransactionLocal->Commit(TRUE, 0, 0), S_OK);
|
|
// check retain property
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
}
|
|
|
|
// check column was dropped (oldCD must contains new CD and rgColumnDesc[0])
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &newCD, &newlen);
|
|
if (DBPROPVAL_TC_DML == vSupportedTxnDDL.lVal)
|
|
{ // check column was not dropped
|
|
COMPARE(AreColEqual(oldCD, oldlen, newCD, newlen), TRUE);
|
|
}
|
|
else
|
|
{ // check column was dropped
|
|
COMPARE(CheckColInfo(newCD, newlen, oldCD, oldlen, &oldCD[nCol-1]), TRUE);
|
|
}
|
|
ReleaseColumnDesc(newCD, newlen);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
m_hr = m_pTable->DropTable();
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit without retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_20()
|
|
{
|
|
TBEGIN
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBCOLUMNDESC *newCD = NULL, *oldCD = NULL;
|
|
DBORDINAL newlen = 0, oldlen = 0;
|
|
CCol col;
|
|
DBORDINAL nCol;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
// create a table
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
|
|
// start the transaction
|
|
TESTC_(m_hr = StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// try to drop a column from table
|
|
nCol = (ULONG)rand()%m_pTable->CountColumnsOnTable()+1;
|
|
col = m_pTable->GetColInfoForUpdate(nCol);
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_pITableDefinition->DropColumn(&m_pTable->GetTableID(),
|
|
col.GetColID()), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
CHECK(m_pITableDefinition->DropColumn(&m_pTable->GetTableID(),
|
|
col.GetColID()), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// commit without retaining
|
|
CHECK(m_hr = pITransactionLocal->Commit(FALSE, 0, 0), S_OK);
|
|
// check retaining / nont retaining prop
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE),
|
|
FAILED(m_hr)? S_OK: XACT_E_NOTRANSACTION);
|
|
}
|
|
|
|
// check column was dropped (oldCD must contains new CD and rgColumnDesc[0])
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &newCD, &newlen);
|
|
if (DBPROPVAL_TC_DML == vSupportedTxnDDL.lVal)
|
|
{ // check column was not dropped
|
|
COMPARE(AreColEqual(oldCD, oldlen, newCD, newlen), TRUE);
|
|
}
|
|
else
|
|
{ // check column was dropped
|
|
COMPARE(CheckColInfo(newCD, newlen, oldCD, oldlen, &oldCD[nCol-1]), TRUE);
|
|
}
|
|
ReleaseColumnDesc(newCD, newlen);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
m_hr = m_pTable->DropTable();
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
//
|
|
// @cmember Thread function for TCDropColumn
|
|
//----------------------------------------------------------------------
|
|
unsigned TCDropColumn::MyThreadProc(ULONG i)
|
|
{
|
|
DBID ColumnID;
|
|
HRESULT hr;
|
|
|
|
if (i>= nThreads)
|
|
return 0;
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = m_rgName[i];
|
|
Sleep(0); // switch the context
|
|
|
|
hr = m_pITableDefinition->DropColumn(&m_pTable->GetTableID(), &ColumnID);
|
|
Sleep(0); // switch the context
|
|
|
|
m_rgResult[i] = hr;
|
|
return 1;
|
|
} //TCDropColumn::MyThreadProc
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc threads on different columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_21()
|
|
{
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
BOOL fTestResult = TEST_FAIL;
|
|
ULONG i;
|
|
ULONG newnThreads;
|
|
CCol col;
|
|
|
|
// create nThreads names and init the results
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
if (m_cColumnDesc < 2)
|
|
{
|
|
odtLog << "There are too few columns in the table\n";
|
|
goto CLEANUP;
|
|
}
|
|
newnThreads = (nThreads <= (ULONG)m_cColumnDesc) ? nThreads: (ULONG)m_cColumnDesc;
|
|
for (i=0; i< newnThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
col = m_pTable->GetColInfoForUpdate(i+1);
|
|
m_rgName[i] = wcsDuplicate(col.GetColName());
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// creates a table, build m_rgColumnDesc by it
|
|
for (i=0; i<newnThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(newnThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< newnThreads; i++)
|
|
{
|
|
CloseHandle(hrgThread[i]);
|
|
SAFE_FREE(m_rgName[i]);
|
|
}
|
|
|
|
for (i=0; i<newnThreads; i++)
|
|
TESTC_(m_rgResult[i], S_OK);
|
|
fTestResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
DropTableAndCheck(&m_pTable->GetTableID());
|
|
return fTestResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc threads on the same column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_22()
|
|
{
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
BOOL fTestResult = TEST_FAIL;
|
|
ULONG i, nS_OK, nDB_E_NOCOLUMN;
|
|
CCol col;
|
|
DBORDINAL nCol;
|
|
|
|
// create n names and init the results
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
if (m_cColumnDesc < 1)
|
|
{
|
|
odtLog << "There are too few columns in the table\n";
|
|
goto CLEANUP;
|
|
}
|
|
nCol = (ULONG)rand()%m_pTable->CountColumnsOnTable()+1;
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
col = m_pTable->GetColInfoForUpdate(nCol);
|
|
m_rgName[i] = wcsDuplicate(col.GetColName());
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// creates a table, build m_rgColumnDesc by it
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
CloseHandle(hrgThread[i]);
|
|
SAFE_FREE(m_rgName[i]);
|
|
}
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
for (i=nS_OK=nDB_E_NOCOLUMN=0; i<nThreads; i++)
|
|
{
|
|
if (m_rgResult[i] == S_OK)
|
|
nS_OK++;
|
|
else if (CHECK(m_rgResult[i], g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN))
|
|
nDB_E_NOCOLUMN++;
|
|
else
|
|
goto CLEANUP;
|
|
}
|
|
TESTC(nS_OK == 1 && nDB_E_NOCOLUMN == nThreads-1);
|
|
fTestResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
DropTableAndCheck(&m_pTable->GetTableID());
|
|
return fTestResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a column twice => DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_23()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
DBKIND_NAME != m_pTable->GetTableID().eKind? m_pTable->GetTableID().uName.pwszName: NULL);
|
|
|
|
col = m_pTable->GetColInfoForUpdate((ULONG)rand()%m_pTable->CountColumnsOnTable()+1);
|
|
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), S_OK);
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 2 TableDefinition interfaces on the same table, try to drop 2 different columns => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_24()
|
|
{
|
|
TBEGIN
|
|
ITableDefinition *pITableDefinition = NULL;
|
|
CCol col;
|
|
|
|
TESTC(VerifyInterface(m_pIOpenRowset, IID_ITableDefinition, SESSION_INTERFACE, (IUnknown**)&pITableDefinition));
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
DBKIND_NAME != m_pTable->GetTableID().eKind? m_pTable->GetTableID().uName.pwszName: NULL);
|
|
|
|
col = m_pTable->GetColInfoForUpdate(1);
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), S_OK);
|
|
|
|
col = m_pTable->GetColInfoForUpdate(2);
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID(), pITableDefinition), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITableDefinition);
|
|
m_hr = m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop as many column as possible from a table created with a SQL statement
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_25()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i, cColumns;
|
|
BOOL fOldTableCreation = GetModInfo()->UseITableDefinition(FALSE);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
IDBCreateCommand *pIDBCreateCommand = NULL;
|
|
|
|
// check whether commands are supported
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_IDBCreateCommand,
|
|
SESSION_INTERFACE, (IUnknown**)&pIDBCreateCommand));
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
TESTC(GetColumnDescOnTable(&m_pTable->GetTableID(), &rgColumnDesc, &cColumns));
|
|
|
|
for (i=0; i<cColumns-1; i++)
|
|
{
|
|
if ( !CHECK(m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[i].dbcid), S_OK) )
|
|
odtLog << "could not drop the column \n";
|
|
}
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[cColumns-1].dbcid);
|
|
odtLog << ((SUCCEEDED(m_hr)) ? "\tlast column was dropped\n" : "\t could not drop the last column\n");
|
|
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
GetModInfo()->UseITableDefinition(fOldTableCreation);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumns, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a column from a 2 column table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_26()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
ULONG cColumnDesc = 2;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[0].dbcid), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc drop a column from a 1 column table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_27()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
ULONG cColumnDesc = 1;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &rgColumnDesc[0].dbcid);
|
|
|
|
if (S_OK == m_hr)
|
|
odtLog << "the only column of the table was dropped\n";
|
|
else
|
|
odtLog << "could not drop the only column of the table\n";
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc drop a column from a non empty table => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_28()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(10, 0), S_OK);
|
|
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
DBKIND_NAME != m_pTable->GetTableID().eKind? m_pTable->GetTableID().uName.pwszName: NULL);
|
|
|
|
col = m_pTable->GetColInfoForUpdate((ULONG)rand()%m_pTable->CountColumnsOnTable()+1);
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc drop a column from an empty table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_29()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
DBKIND_NAME != m_pTable->GetTableID().eKind? m_pTable->GetTableID().uName.pwszName: NULL);
|
|
|
|
col = m_pTable->GetColInfoForUpdate((ULONG)rand()%m_pTable->CountColumnsOnTable()+1);
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), col.GetColID()), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc drop a nullable, an autoincrementable and a default value column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_30()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL nAutoInc;
|
|
DBORDINAL nNull;
|
|
DBORDINAL nDefault;
|
|
DBORDINAL i;
|
|
BOOL fFound = FALSE;
|
|
VARIANT defVal;
|
|
DBID ColumnID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CCol col;
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN));
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_COL_AUTOINCREMENT, DBPROPSET_COLUMN));
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN));
|
|
|
|
pTable->CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// get an autoincrementable column
|
|
nAutoInc = cColumnDesc;
|
|
for (i=0; i < cColumnDesc && !fFound; i++)
|
|
{
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
if (TRUE == (fFound = col.CanAutoInc()))
|
|
nAutoInc = i;
|
|
}
|
|
|
|
TESTC(nAutoInc < cColumnDesc);
|
|
|
|
// get the nullable and default columns
|
|
nNull = (nAutoInc+1) % cColumnDesc;
|
|
nDefault = (nAutoInc+2) % cColumnDesc;
|
|
|
|
// set autoincrementable property on a column
|
|
SetProperty(&rgColumnDesc[nAutoInc].rgPropertySets, &rgColumnDesc[nAutoInc].cPropertySets,
|
|
DBPROP_COL_AUTOINCREMENT, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
// set nullable property on a column (also add default for it)
|
|
SetProperty(&rgColumnDesc[nNull].rgPropertySets, &rgColumnDesc[nNull].cPropertySets,
|
|
DBPROP_COL_NULLABLE, VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
VariantInit(&defVal);
|
|
GetDefaultValue(&rgColumnDesc[nNull], &defVal, pTable);
|
|
SetDefaultProperty(&rgColumnDesc[nNull].rgPropertySets, &rgColumnDesc[nNull].cPropertySets,
|
|
&defVal, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&defVal);
|
|
// set default column
|
|
GetDefaultValue(&rgColumnDesc[nDefault], &defVal, pTable);
|
|
SetDefaultProperty(&rgColumnDesc[nDefault].rgPropertySets, &rgColumnDesc[nDefault].cPropertySets,
|
|
&defVal, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&defVal);
|
|
|
|
// create the table with a autoinc column, a nullable one and a default one
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
DuplicateDBID(rgColumnDesc[nAutoInc].dbcid, &ColumnID);
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (S_OK != m_hr)
|
|
odtLog << "could not drop the autoincrementable column\n";
|
|
else
|
|
odtLog << "the autoincrementable column was dropped \n";
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
|
|
DuplicateDBID(rgColumnDesc[nNull].dbcid, &ColumnID);
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (S_OK != m_hr)
|
|
odtLog << "could not drop the nullable column\n";
|
|
else
|
|
odtLog << "the nullable column was dropped \n";
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
|
|
DuplicateDBID(m_rgColumnDesc[nDefault].dbcid, &ColumnID);
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (S_OK != m_hr)
|
|
odtLog << "could not drop the default value column\n";
|
|
else
|
|
odtLog << "the default value column was dropped \n";
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
|
|
CLEANUP:
|
|
delete pTable;
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc try to drop a column from a view
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_31()
|
|
{
|
|
TBEGIN
|
|
LPWSTR pwszViewName = L"HagiView"; // just a view name
|
|
DBID TableID;
|
|
CCol col;
|
|
IDBCreateCommand *pIDBCreateCommand = NULL;
|
|
|
|
// check whether commands are supported
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_IDBCreateCommand,
|
|
SESSION_INTERFACE, (IUnknown**)&pIDBCreateCommand));
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition, m_pTable->GetTableName());
|
|
|
|
// create the view
|
|
m_pTable->SetViewName(pwszViewName);
|
|
if ( S_OK != (m_hr = m_pTable->ExecuteCommand(
|
|
CREATE_VIEW,
|
|
IID_NULL,
|
|
pwszViewName, // the table name will be the implicit one
|
|
NULL, // don't return the command statement
|
|
0,
|
|
NULL,
|
|
EXECUTE_IFNOERROR // execute the command
|
|
))
|
|
)
|
|
{
|
|
odtLog << "\t the view cannot be created\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
TESTC_(m_hr, S_OK);
|
|
|
|
// try to drop a column from the view
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = L"HagiTable";
|
|
col = m_pTable->GetColInfoForUpdate((ULONG)rand()%m_pTable->CountColumnsOnTable()+1);
|
|
m_hr = DropColumnAndCheck(&TableID, col.GetColID());
|
|
odtLog << ((S_OK == m_hr) ? "column was dropped from view\n" : "could not drop column from view\n");
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
// drop the view!
|
|
if (m_pTable->GetTableName())
|
|
m_hr = m_pTable->ExecuteCommand(
|
|
DROP_VIEW,
|
|
IID_NULL,
|
|
pwszViewName, // the table name will be the implicit one
|
|
NULL, // don't return the command statement
|
|
0,
|
|
NULL,
|
|
EXECUTE_IFNOERROR // execute the command
|
|
);
|
|
CHECK(m_hr = m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc drop a column added with an alter table command => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_32()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
LPWSTR pwszColumnName = L"intHagi"; // the name of the integer column
|
|
LPWSTR pwszColNameAndType = NULL;
|
|
IDBCreateCommand *pIDBCreateCommand = NULL;
|
|
|
|
// check whether commands are supported
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_IDBCreateCommand,
|
|
SESSION_INTERFACE, (IUnknown**)&pIDBCreateCommand));
|
|
|
|
TESTC(NULL != m_rgColumnDesc[0].pwszTypeName); // it should be a numeric type
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// build the column name and type argument of the command
|
|
SAFE_ALLOC(pwszColNameAndType, WCHAR, wcslen(pwszColumnName)+wcslen(m_rgColumnDesc[0].pwszTypeName)+2);
|
|
wcscpy(pwszColNameAndType, pwszColumnName);
|
|
wcscat(pwszColNameAndType, L" ");
|
|
wcscat(pwszColNameAndType, m_rgColumnDesc[0].pwszTypeName);
|
|
|
|
// create the ALTER SQL statement
|
|
if ( S_OK != (m_hr = m_pTable->ExecuteCommand(
|
|
ALTER_TABLE_ADD,
|
|
IID_NULL,
|
|
pwszColNameAndType, // the table name will be the implicit one
|
|
NULL, // don't return the command statement
|
|
0,
|
|
NULL,
|
|
EXECUTE_IFNOERROR // execute the command
|
|
))
|
|
)
|
|
{
|
|
odtLog << "Could not add a column in the table, using commands\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// try to drop the new column from the table
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = pwszColumnName;
|
|
TESTC_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
SAFE_FREE(pwszColNameAndType);
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc try to drop columns using different DBKIND pattern
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_33()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
CCol col;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
// try to drop a column
|
|
col = m_pTable->GetColInfoForUpdate(2);
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = wcsDuplicate(col.GetColName());
|
|
if (m_cColumnDesc > 2)
|
|
{
|
|
CHECK(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), S_OK);
|
|
}
|
|
else
|
|
{
|
|
odtLog << "too few columns, skipped the drop column given by name case \n";
|
|
}
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
|
|
col = m_pTable->GetColInfoForUpdate(4);
|
|
ColumnID.eKind = DBKIND_GUID;
|
|
memset(&ColumnID.uGuid.guid, 0, sizeof(GUID));
|
|
|
|
//NOTE: spec was changed in MDAC 2.6 to replace DB_E_BADCOLUMNID with DB_E_NOCOLUMN
|
|
// for ITableDefinition::DropColumn. So when runnning against MDAC 2.5 expect DB_E_BADCOLUMNID
|
|
// This is for SQL-specific provider. For other providers, you should modify this to test against your target spec
|
|
if (!CHECK(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN))
|
|
{
|
|
odtLog << "error at the guid case\n";
|
|
}
|
|
|
|
col = m_pTable->GetColInfoForUpdate(3);
|
|
ColumnID.eKind = DBKIND_GUID_NAME;
|
|
ColumnID.uGuid.guid = guidModule;
|
|
ColumnID.uName.pwszName = col.GetColName();
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (!CHECK(m_hr, g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN))
|
|
{
|
|
odtLog << "error at the guid name case\n";
|
|
}
|
|
|
|
ColumnID.eKind = DBKIND_GUID_PROPID;
|
|
memset(&ColumnID.uGuid.guid, 0, sizeof(GUID));
|
|
ColumnID.uName.ulPropid = 0L;
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (!CHECK(m_hr, g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN) )
|
|
{
|
|
odtLog << "error at the guid propid case\n";
|
|
}
|
|
|
|
ColumnID.eKind = DBKIND_PGUID_NAME;
|
|
ColumnID.uGuid.pguid = &guidModule;
|
|
ColumnID.uName.pwszName = NULL;
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (!CHECK(m_hr, g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN))
|
|
{
|
|
odtLog << "error at the pguid name case\n";
|
|
}
|
|
|
|
ColumnID.eKind = DBKIND_PGUID_PROPID;
|
|
ColumnID.uGuid.pguid = &guidModule;
|
|
ColumnID.uName.ulPropid = 0L;
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (!CHECK(m_hr, g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN) )
|
|
{
|
|
odtLog << "error at the pguid propid case\n";
|
|
}
|
|
|
|
ColumnID.eKind = DBKIND_PROPID;
|
|
ColumnID.uName.ulPropid = 0L;
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (!CHECK(m_hr, g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN))
|
|
{
|
|
odtLog << "error at the propid case\n";
|
|
}
|
|
|
|
ColumnID.eKind = 0xff;
|
|
m_hr = DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID);
|
|
if (!CHECK(m_hr, g_fSQLOLEDB25 ? DB_E_BADCOLUMNID : DB_E_NOCOLUMN))
|
|
{
|
|
odtLog << "error at the inexistent value for eKind case\n";
|
|
}
|
|
|
|
CLEANUP:
|
|
CHECK(m_hr = m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Fully Qualified Table Name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_34()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
WCHAR *pwszQualTableName = NULL;
|
|
WCHAR *pwszCatalogName = NULL;
|
|
WCHAR *pwszSchemaName = NULL;
|
|
WCHAR *pwszTableName = NULL;
|
|
CCol col;
|
|
|
|
// create a regular table
|
|
TESTC(NULL != m_pTable);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
pwszTableName = m_pTable->GetTableName();
|
|
TableID.eKind = DBKIND_NAME;
|
|
|
|
TESTC(GetCatalogSchemaNames(pwszTableName, &pwszCatalogName, &pwszSchemaName));
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(m_pTable->GetQualifiedName(pwszCatalogName, pwszSchemaName, pwszTableName, &pwszQualTableName),S_OK);
|
|
TableID.uName.pwszName = pwszQualTableName;
|
|
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
DBKIND_NAME != m_pTable->GetTableID().eKind? m_pTable->GetTableID().uName.pwszName: NULL);
|
|
col = m_pTable->GetColInfoForUpdate(1);
|
|
|
|
TESTC_(DropColumnAndCheck(&TableID, col.GetColID(), NULL, &m_pTable->GetTableID()), S_OK);
|
|
|
|
CLEANUP:
|
|
m_pTable->DropTable();
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
SAFE_FREE(pwszQualTableName);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Quoted Table Name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropColumn::Variation_35()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
CCol col;
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
TESTC(NULL != m_pTable);
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
|
|
m_pTable->GetQuotedName(m_pTable->GetTableName(), &TableID.uName.pwszName);
|
|
|
|
m_pTable->AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
DBKIND_NAME != m_pTable->GetTableID().eKind? m_pTable->GetTableID().uName.pwszName: NULL);
|
|
col = m_pTable->GetColInfoForUpdate(1);
|
|
|
|
TESTC_(DropColumnAndCheck(&TableID, col.GetColID()), S_OK);
|
|
|
|
CLEANUP:
|
|
m_pTable->DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCDropColumn::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCDropTable)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCDropTable - Test Case fo dropping a table
|
|
//| Created: 09/11/97
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCDropTable::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
// TO DO: Add your own code here
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_1()
|
|
{
|
|
|
|
if ( !CHECK(m_hr = m_pITableDefinition->DropTable(NULL), E_INVALIDARG))
|
|
return TEST_FAIL;
|
|
else
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pTableID is DB_NULLID => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_2()
|
|
{
|
|
DBID TableID;
|
|
|
|
TableID = DB_NULLID;
|
|
if ( !CHECK(m_hr = m_pITableDefinition->DropTable(&TableID), DB_E_NOTABLE))
|
|
return TEST_FAIL;
|
|
else
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length for table name => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_3()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
WCHAR* pwszTableName = NULL;
|
|
DBID TableID;
|
|
|
|
// create a maximum size table name
|
|
m_pTable->MakeTableName(NULL);
|
|
GetLiteralInfo();
|
|
pwszTableName = BuildValidName(m_cMaxTableName, m_pTable->GetTableName());
|
|
odtLog << "king size table name: " << pwszTableName << ", i.e." << (wcslen(pwszTableName)) << " characters\n";
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0, pwszTableName), S_OK);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = pwszTableName;
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&TableID), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
m_pTable->DropTable();
|
|
PROVIDER_FREE(pwszTableName);
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 1-char-too-long table name => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_4()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
WCHAR* pwszTableName = NULL, *pwszTableName1 = NULL;
|
|
DBID TableID;
|
|
|
|
// create a maximum size table name
|
|
m_pTable->MakeTableName(NULL);
|
|
GetLiteralInfo();
|
|
pwszTableName = BuildValidName(m_cMaxTableName, m_pTable->GetTableName());
|
|
pwszTableName1 = BuildValidName(m_cMaxTableName+1, m_pTable->GetTableName());
|
|
odtLog << "1 char too long table name: " << pwszTableName1 << ", i.e."
|
|
<< wcslen(pwszTableName1) << " characters\n";
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0, pwszTableName), S_OK);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = pwszTableName1;
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&TableID), DB_E_NOTABLE);
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
CHECK(m_pTable->DropTable(), S_OK);
|
|
PROVIDER_FREE(pwszTableName);
|
|
PROVIDER_FREE(pwszTableName1);
|
|
m_pTable->DropTable();
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc The pointer to the table name is NULL => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_5()
|
|
{
|
|
DBID TableID;
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
if ( !CHECK(m_hr = m_pITableDefinition->DropTable(&TableID), DB_E_NOTABLE))
|
|
return TEST_FAIL;
|
|
else
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table name is empty => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_6()
|
|
{
|
|
DBID TableID;
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = L"";
|
|
if ( !CHECK(m_hr = m_pITableDefinition->DropTable(&TableID), DB_E_NOTABLE))
|
|
return TEST_FAIL;
|
|
else
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid table name => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_7()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
WCHAR* pwszTableName = NULL;
|
|
size_t m;
|
|
DBID TableID;
|
|
|
|
// create an invalid table name
|
|
m_pTable->MakeTableName(NULL);
|
|
GetLiteralInfo();
|
|
m = min(wcslen(m_pTable->GetTableName())+5, m_cMaxTableName);
|
|
pwszTableName = BuildInvalidName(m, m_pTable->GetTableName(), m_pwszInvalidTableChars);
|
|
odtLog << "invalid table name: " << pwszTableName << ", i.e." << wcslen(pwszTableName) << " characters\n";
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = pwszTableName;
|
|
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&TableID), DB_E_NOTABLE);
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(pwszTableName);
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc A rowset is opened on table => DB_E_TABLEINUSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_8()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL, fExists;
|
|
IRowset* pIRowset = NULL;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
TESTC_(m_pIOpenRowset->OpenRowset(NULL, &m_pTable->GetTableID(), NULL, IID_IRowset,
|
|
0, NULL, (IUnknown**)&pIRowset), S_OK);
|
|
|
|
fTestRes = TEST_PASS;
|
|
//try to drop the table
|
|
m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID());
|
|
if (DB_E_TABLEINUSE != m_hr && !CHECK(m_hr, S_OK))
|
|
{
|
|
odtLog << "The table was dropped, though in use \n";
|
|
fTestRes = TEST_FAIL;
|
|
}
|
|
else
|
|
{
|
|
odtLog << ((DB_E_TABLEINUSE == m_hr) ? "DB_E_TABLEINUSE returned\n": "S_OK returned\n");
|
|
|
|
//check the table still exist
|
|
if (!CHECK(m_pTable->DoesTableExist(&m_pTable->GetTableID(), &fExists), S_OK) ||
|
|
(fExists==(S_OK == m_hr)))
|
|
fTestRes = TEST_FAIL;
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowset);
|
|
m_pTable->DropTable();
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table in use => DB_E_TABLEINUSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_9()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL, fExists;
|
|
IRowset* pIRowset = NULL;
|
|
|
|
m_pTable->SetRIID((struct _GUID*)&IID_IRowset);
|
|
m_pTable->SetRowset((IUnknown**)&pIRowset);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_pTable->CreateTable(10, 1), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
|
|
//try to release drop the table
|
|
m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID());
|
|
if (DB_E_TABLEINUSE != m_hr && S_OK != m_hr)
|
|
{
|
|
odtLog << "The table was dropped, though in use \n";
|
|
fTestRes = TEST_FAIL;
|
|
}
|
|
else
|
|
{
|
|
odtLog << ((DB_E_TABLEINUSE == m_hr) ? "DB_E_TABLEINUSE returned\n" : "S_OK returned\n");
|
|
|
|
//check the table still exist
|
|
if (!CHECK(m_pTable->DoesTableExist(&m_pTable->GetTableID(), &fExists), S_OK) || (fExists==(S_OK == m_hr)))
|
|
fTestRes = TEST_FAIL;
|
|
}
|
|
|
|
CLEANUP:
|
|
m_pTable->SetRowset(NULL);
|
|
m_pTable->DropTable();
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent table => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_10()
|
|
{
|
|
WCHAR* pwszTableName = NULL;
|
|
DBID TableID;
|
|
|
|
// create a new valid table name
|
|
m_pTable->MakeTableName(NULL);
|
|
pwszTableName = m_pTable->GetTableName();
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = pwszTableName;
|
|
if (!CHECK(m_hr = m_pITableDefinition->DropTable(&TableID), DB_E_NOTABLE))
|
|
return TEST_FAIL;
|
|
else
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort with retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_11()
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0,0), S_OK);
|
|
|
|
TESTC_(m_hr = StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(DropTableAndCheck(&m_pTable->GetTableID()), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned on further table access
|
|
TESTC_(DropTableAndCheck(&m_pTable->GetTableID()), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// abort retaining
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, TRUE, FALSE), S_OK);
|
|
// check retaining
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
}
|
|
|
|
// check table existence
|
|
CHECK(m_hr = m_pTable->DoesTableExist(&m_pTable->GetTableID(), &fExists), S_OK);
|
|
COMPARE(fExists, DBPROPVAL_TC_DDL_IGNORE != vSupportedTxnDDL.lVal
|
|
&& DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort without retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_12()
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0,0), S_OK);
|
|
|
|
TESTC_(m_hr = StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
TESTC_(DropTableAndCheck(&m_pTable->GetTableID()), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned on further table operations
|
|
TESTC_(DropTableAndCheck(&m_pTable->GetTableID()), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// abort non retaining
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
// check not retaining
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE),
|
|
FAILED(m_hr)? S_OK : XACT_E_NOTRANSACTION);
|
|
}
|
|
|
|
// check table existence
|
|
CHECK(m_hr = m_pTable->DoesTableExist(&m_pTable->GetTableID(), &fExists), S_OK);
|
|
COMPARE(fExists, DBPROPVAL_TC_DDL_IGNORE != vSupportedTxnDDL.lVal
|
|
&& DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit with retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_13()
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0,0), S_OK);
|
|
|
|
TESTC_(m_hr = StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
TESTC_(DropTableAndCheck(&m_pTable->GetTableID()), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
TESTC_(DropTableAndCheck(&m_pTable->GetTableID()), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// commit retaining
|
|
CHECK(m_hr = pITransactionLocal->Commit(TRUE, 0, 0), S_OK);
|
|
// check retaining
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
}
|
|
|
|
// check table existence
|
|
CHECK(m_hr = m_pTable->DoesTableExist(&m_pTable->GetTableID(), &fExists), S_OK);
|
|
COMPARE(fExists, DBPROPVAL_TC_DML == vSupportedTxnDDL.lVal);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit without retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_14()
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0,0), S_OK);
|
|
|
|
TESTC_(m_hr = StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
TESTC_(DropTableAndCheck(&m_pTable->GetTableID()), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
TESTC_(DropTableAndCheck(&m_pTable->GetTableID()), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
// commit not retaining
|
|
CHECK(m_hr = pITransactionLocal->Commit(FALSE, 0, 0), S_OK);
|
|
// check not retaining
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE),
|
|
FAILED(m_hr)? S_OK: XACT_E_NOTRANSACTION);
|
|
}
|
|
|
|
// check whether the transaction was aborted
|
|
CHECK(m_hr = m_pTable->DoesTableExist(&m_pTable->GetTableID(), &fExists), S_OK);
|
|
COMPARE(fExists, DBPROPVAL_TC_DML == vSupportedTxnDDL.lVal);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a table created with an SQL command => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_15()
|
|
{
|
|
TBEGIN
|
|
IDBCreateCommand *pIDBCreateCommand = NULL;
|
|
|
|
// check whether commands are supported
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_IDBCreateCommand,
|
|
SESSION_INTERFACE, (IUnknown**)&pIDBCreateCommand));
|
|
|
|
GetModInfo()->UseITableDefinition(FALSE);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
GetModInfo()->UseITableDefinition(TRUE);
|
|
m_pTable->DropTable();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a table created with ITableDefinition, no rowset created => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_16()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(10, 0), S_OK);
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
m_pTable->DropTable();
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a table created with ITableDefinition, rowset released => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_17()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
IRowset *pIRowset = NULL;
|
|
|
|
m_pTable->SetRowset((IUnknown**)&pIRowset);
|
|
m_pTable->SetRIID((struct _GUID*)&IID_IRowset);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
SAFE_RELEASE(pIRowset);
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
CLEANUP:
|
|
m_pTable->SetRowset(NULL);
|
|
m_pTable->DropTable();
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ITableDefinition::CreateTable, insert 10 rows, release rowset, drop the table => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_18()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
IRowset *pIRowset = NULL;
|
|
|
|
m_pTable->SetRowset((IUnknown**)&pIRowset);
|
|
m_pTable->SetRIID((struct _GUID*)&IID_IRowset);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(10, 0), S_OK);
|
|
SAFE_RELEASE(pIRowset);
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
CLEANUP:
|
|
m_pTable->SetRowset(NULL);
|
|
m_pTable->DropTable();
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc For each provider type, create a table with a single column and then drop it => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_19()
|
|
{
|
|
BOOL fTestRes = TEST_PASS;
|
|
DBORDINAL i;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->SetBuildColumnDesc(FALSE);
|
|
m_pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << "\t" << rgColumnDesc[i].pwszTypeName;
|
|
m_pTable->SetColumnDesc(NULL);
|
|
m_pTable->SetColumnDesc(&rgColumnDesc[i], 1);
|
|
if (!CHECK(m_hr = m_pTable->CreateTable(0, 0), S_OK))
|
|
{
|
|
fTestRes = TEST_FAIL;
|
|
continue;
|
|
}
|
|
|
|
if (!CHECK(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), S_OK))
|
|
{
|
|
odtLog << "\n Error for type" << rgColumnDesc[i].pwszTypeName << "\n";
|
|
fTestRes = TEST_FAIL;
|
|
}
|
|
m_pTable->DropTable();
|
|
}
|
|
odtLog << "\n";
|
|
|
|
m_pTable->SetColumnDesc(NULL);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a table twice => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_20()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), S_OK);
|
|
TESTC_(m_hr = m_pITableDefinition->DropTable(&m_pTable->GetTableID()), DB_E_NOTABLE);
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
return fTestRes;
|
|
}
|
|
// }}
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
//
|
|
// @cmember Thread procedure for TCDropTable
|
|
//----------------------------------------------------------------------
|
|
unsigned TCDropTable::MyThreadProc(ULONG i)
|
|
{
|
|
DBID TableID;
|
|
HRESULT hr;
|
|
|
|
if (i>= nThreads)
|
|
return 0;
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_rgName[i];
|
|
Sleep(0); // switch the context
|
|
|
|
hr = m_pITableDefinition->DropTable(&TableID);
|
|
Sleep(0); // switch the context
|
|
|
|
m_rgResult[i] = hr;
|
|
return 1;
|
|
} //TCDropTable::MyThreadProc
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc threads on different tables
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_21()
|
|
{
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
BOOL fTestResult = TEST_FAIL;
|
|
ULONG i;
|
|
DBID TableID;
|
|
|
|
// create n names and init the results
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
m_rgName[i] = NULL;
|
|
m_rgResult[i] = E_FAIL;
|
|
}
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
m_rgName[i] = wcsDuplicate(m_pTable->GetTableName());
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// creates a table, build rgColumnDesc by it
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
TESTC_(m_rgResult[i], S_OK);
|
|
fTestResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
TableID.eKind = DBKIND_NAME;
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
TableID.uName.pwszName = m_rgName[i];
|
|
// if the table was not dropped by the corresponding thread, try again
|
|
if (FAILED(m_rgResult[i]))
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
PROVIDER_FREE(m_rgName[i]);
|
|
}
|
|
return fTestResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc threads on same table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_22()
|
|
{
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
BOOL fTestResult = TEST_FAIL;
|
|
ULONG i;
|
|
ULONG nS_OK = 0;
|
|
ULONG nDB_E_NOTABLE = 0;
|
|
LPWSTR pwszBaseName = NULL;
|
|
DBID TableID;
|
|
|
|
// create n names and init the results
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
pwszBaseName = m_pTable->GetTableName();
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = E_FAIL;
|
|
m_rgName[i] = pwszBaseName;
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// creates a table, build rgColumnDesc by it
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=nS_OK=nDB_E_NOTABLE=0; i<nThreads; i++)
|
|
{
|
|
if (m_rgResult[i] == S_OK)
|
|
nS_OK++;
|
|
else if (CHECK(m_rgResult[i], DB_E_NOTABLE))
|
|
nDB_E_NOTABLE++;
|
|
else
|
|
{
|
|
odtLog << "Thread " << i << ": unexpected result " << m_rgResult[i] << "\n";
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
TESTC(nS_OK == 1 && nDB_E_NOTABLE == nThreads-1);
|
|
fTestResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = pwszBaseName;
|
|
if (nS_OK < 1)
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
return fTestResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Fully Qualified Table Name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_23()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
DBID TableID;
|
|
WCHAR *pwszQualTableName = NULL;
|
|
WCHAR *pwszCatalogName = NULL;
|
|
WCHAR *pwszSchemaName = NULL;
|
|
WCHAR *pwszTableName = NULL;
|
|
|
|
// create a regular table
|
|
TESTC(NULL != m_pTable);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
pwszTableName = m_pTable->GetTableName();
|
|
TableID.eKind = DBKIND_NAME;
|
|
|
|
TESTC(GetCatalogSchemaNames(pwszTableName, &pwszCatalogName, &pwszSchemaName));
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(m_pTable->GetQualifiedName(pwszCatalogName, pwszSchemaName, pwszTableName, &pwszQualTableName),S_OK);
|
|
TableID.uName.pwszName = pwszQualTableName;
|
|
|
|
// drop the table
|
|
TESTC_(DropTableAndCheck(&TableID), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
SAFE_FREE(pwszQualTableName);
|
|
m_pTable->DropTable();
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Quoted Table Name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_24()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
DBID TableID;
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
TESTC(NULL != m_pTable);
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
TESTC_(m_pTable->CreateTable(0, 0), S_OK);
|
|
m_pTable->GetQuotedName(m_pTable->GetTableName(), &TableID.uName.pwszName);
|
|
|
|
TESTC_(DropTableAndCheck(&TableID), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(&TableID, FALSE);
|
|
m_pTable->DropTable();
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Different DBKINDs for pTableID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropTable::Variation_25()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
|
|
m_pTable->SetBuildColumnDesc(TRUE);
|
|
|
|
// try to drop a column
|
|
TableID.eKind = DBKIND_NAME;
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
TableID.uName.pwszName = m_pTable->GetTableID().uName.pwszName;
|
|
|
|
TableID.eKind = DBKIND_GUID;
|
|
TableID.uGuid.guid = guidModule;
|
|
if (!CHECK(DropTableAndCheck(&TableID), DB_E_NOTABLE))
|
|
{
|
|
odtLog << "error at the guid case\n";
|
|
}
|
|
CHECK(m_hr = m_pTable->DropTable(), S_OK);
|
|
|
|
TableID.eKind = DBKIND_GUID_NAME;
|
|
TableID.uGuid.guid = guidModule;
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
TableID.uName.pwszName = m_pTable->GetTableID().uName.pwszName;
|
|
if (!CHECK(DropTableAndCheck(&TableID), DB_E_NOTABLE))
|
|
{
|
|
odtLog << "error at the guid name case\n";
|
|
}
|
|
CHECK(m_hr = m_pTable->DropTable(), S_OK);
|
|
|
|
TableID.eKind = DBKIND_GUID_PROPID;
|
|
TableID.uGuid.guid = guidModule;
|
|
TableID.uName.ulPropid = 0L;
|
|
if (!CHECK(DropTableAndCheck(&TableID), DB_E_NOTABLE))
|
|
{
|
|
odtLog << "error at the guid propid case\n";
|
|
}
|
|
|
|
TableID.eKind = DBKIND_PGUID_NAME;
|
|
TableID.uGuid.pguid = &guidModule;
|
|
TESTC_(m_hr = m_pTable->CreateTable(0, 0), S_OK);
|
|
TableID.uName.pwszName = m_pTable->GetTableID().uName.pwszName;
|
|
if (!CHECK(DropTableAndCheck(&TableID), DB_E_NOTABLE))
|
|
{
|
|
odtLog << "error at the pguid name case\n";
|
|
}
|
|
CHECK(m_hr = m_pTable->DropTable(), S_OK);
|
|
|
|
TableID.eKind = DBKIND_PGUID_PROPID;
|
|
TableID.uGuid.pguid = &guidModule;
|
|
TableID.uName.ulPropid = 0L;
|
|
if (!CHECK(DropTableAndCheck(&TableID), DB_E_NOTABLE))
|
|
{
|
|
odtLog << "error at the pguid propid case\n";
|
|
}
|
|
|
|
TableID.eKind = DBKIND_PROPID;
|
|
TableID.uName.ulPropid = 0L;
|
|
if (!CHECK(DropTableAndCheck(&TableID), DB_E_NOTABLE))
|
|
{
|
|
odtLog << "error at the propid case\n";
|
|
}
|
|
|
|
TableID.eKind = 0xff;
|
|
if (!CHECK(DropTableAndCheck(&TableID), DB_E_NOTABLE))
|
|
{
|
|
odtLog << "error at the inexistent value for eKind case\n";
|
|
}
|
|
|
|
CLEANUP:
|
|
CHECK(m_hr = m_pTable->DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCDropTable::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCCreateTable)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCCreateTable - TestCase for table creation
|
|
//| Created: 09/11/97
|
|
//*-----------------------------------------------------------------------
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
//
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//--------------------------------------------------------------------------
|
|
BOOL TCCreateTable::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Session interfaces
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_1()
|
|
{
|
|
return DefaultObjectTesting(m_pITableDefinition, SESSION_INTERFACE);
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is NULL => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
// checkings, etc
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ppTableID is a NULL pointer => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_3()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID and ppTableID both NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_4()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
0, NULL, TRUE), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pTableID == DB_NULLID => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_5()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(CCNDropTable((DBID*)&DB_NULLID, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
0, NULL), DB_E_BADTABLEID);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cColumnDesc == 0 => E_INVALIDARG or S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_6()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TEST2C_(CCNDropTable(NULL, 0, rgColumnDesc, IID_IRowset, 0, NULL),
|
|
S_OK, E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc rgColumnDesc == NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_7()
|
|
{
|
|
TBEGIN
|
|
|
|
TESTC_(CCNDropTable(NULL, m_cColumnDesc, NULL, IID_IRowset,
|
|
0, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cPropertySets != 0 and rgPropertySets == NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_8()
|
|
{
|
|
TBEGIN
|
|
ULONG ulNonZero = 2;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
ulNonZero, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cPropertySets is 0 and rgPropertySets != NULL => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropertySets[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
FILL_PROP_SET(rgPropertySets[0], 1, rgProp, DBPROPSET_ROWSET)
|
|
FILL_PROP(rgProp[0], DBPROP_IAccessor, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED)
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
0, rgPropertySets), S_OK);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc for a property sets, cProperties != 0 and rgProperties == NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_10()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropertySets[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
FILL_PROP_SET(rgPropertySets[0], 3, NULL, DBPROPSET_ROWSET)
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
1, rgPropertySets), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cProperties == 0 on a property set => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_11()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropertySets[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// FILL_PROP_SET(rgPropertySets[0], 0, rgProp, DBPROPSET_ROWSET)
|
|
rgPropertySets[0].cProperties = 0;
|
|
rgPropertySets[0].rgProperties = rgProp;
|
|
rgPropertySets[0].guidPropertySet = DBPROPSET_ROWSET;
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropertySets), S_OK);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc for a column, rgPropertySets is NULL though cPropertySets != 0 => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_12()
|
|
{
|
|
TBEGIN
|
|
ULONG cProp = 3;
|
|
DBPROPSET rgPropSets[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
rgColumnDesc[0].rgPropertySets = rgPropSets;
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSets);
|
|
FILL_PROP_SET(rgPropSets[0], cProp, NULL, DBPROPSET_COLUMN)
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
// it is not required to release the memory for rgColumnDesc; it will be release in table destructor
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc dbcid in an element of rgColumnDesc is DB_NULLID => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_13()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
// set a dbcid of an element in rgColumnDesc to DB_NULLID
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE); // cleans the container
|
|
memcpy(&rgColumnDesc[0].dbcid, &DB_NULLID, sizeof(DBID));
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc dbcid in an element of rgColumnDesc is NULL => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_14()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set a dbcid of an element in rgColumnDesc to DB_NULLID
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE); // cleans the container
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = NULL;
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc not null pclsid in a DBCOLUMNDESC element
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_15()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
POSITION pos;
|
|
CCol col;
|
|
HRESULT hr;
|
|
BOOL fOleSupported = FALSE;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set pclsid to IID_NULL
|
|
rgColumnDesc[0].pclsid = (GUID*)&IID_NULL;
|
|
|
|
// check whether this is ignored for a non-DBTYPE_IUNKNOWN column
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
|
|
// check DBTYPE_IUNKNOWN is supported
|
|
for (pos = m_ColList.GetHeadPosition(); pos; )
|
|
{
|
|
col = m_ColList.GetNext(pos);
|
|
if (DBTYPE_IUNKNOWN == col.GetProviderType())
|
|
{
|
|
fOleSupported = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check whether a DBTYPE_IUNKNOWN column can be created in the table
|
|
rgColumnDesc[0].wType = DBTYPE_IUNKNOWN;
|
|
PROVIDER_FREE(rgColumnDesc[0].pwszTypeName);
|
|
if (fOleSupported)
|
|
rgColumnDesc[0].pwszTypeName = wcsDuplicate(col.GetProviderTypeName());
|
|
hr = fOleSupported ? S_OK : DB_E_BADTYPE;
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), hr);
|
|
|
|
CLEANUP:
|
|
rgColumnDesc[0].pclsid = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc empty column name => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_16()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
// set a dbcid of an element in rgColumnDesc to DB_NULLID
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE); // cleans the container
|
|
rgColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"");
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc empty table name => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_17()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = L"";
|
|
|
|
// create the empty name table
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADTABLEID);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length for table name => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_18()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// create a maximum size table name
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = BuildValidName(m_cMaxTableName, m_pTable->GetTableName());
|
|
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(&TableID, FALSE);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 1 char too long table name => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_19()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// create a maximum size table name
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = BuildValidName(m_cMaxTableName+1, m_pTable->GetTableName());
|
|
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADTABLEID);
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(&TableID, FALSE);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length column name => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_20()
|
|
{
|
|
TBEGIN
|
|
LPWSTR pwszColumnName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set a dbcid of an element in rgColumnDesc to DB_NULLID
|
|
pwszColumnName = rgColumnDesc[0].dbcid.uName.pwszName;
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = BuildValidName(m_cMaxColName, pwszColumnName);
|
|
// save the number of propertySets, to be able to release it ok
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(pwszColumnName);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 1 char too long column name => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_21()
|
|
{
|
|
TBEGIN
|
|
WCHAR *pwszColumnName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
if (DBKIND_NAME == rgColumnDesc[0].dbcid.eKind)
|
|
pwszColumnName = rgColumnDesc[0].dbcid.uName.pwszName;
|
|
else
|
|
pwszColumnName = wcsDuplicate(L"ColumnName");
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = BuildValidName(m_cMaxColName+1, pwszColumnName);
|
|
// save the number of propertySets, to be able to release it ok
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(pwszColumnName);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ulColumnSize 0 for a variable-length column => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_22()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// go through the list of column and set the column size to 0 for all variable-length columns
|
|
for (ULONG i=0; i<cColumnDesc; i++)
|
|
{
|
|
if (!IsFixedLength(rgColumnDesc[i].wType))
|
|
{
|
|
rgColumnDesc[i].ulColumnSize = 0;
|
|
odtLog << "Column " << rgColumnDesc[i].dbcid.uName.pwszName << " is set to length 0!\n";
|
|
}
|
|
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc For each provider type create and drop a table with a single column => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_23()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *tempColumnDesc;
|
|
DBORDINAL i;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// go through the list of column and set the column size to 0 for all variable-length columns
|
|
for (i=0, tempColumnDesc=rgColumnDesc; i<cColumnDesc; i++, tempColumnDesc++)
|
|
{
|
|
odtLog << "Create a table with a single column " << tempColumnDesc->dbcid.uName.pwszName << "\n";
|
|
CHECK(CCNDropTable(NULL, 1, tempColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid table name => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_24()
|
|
{
|
|
TBEGIN
|
|
WCHAR *pwszTableName = NULL;
|
|
size_t n, m;
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
m = min(n=wcslen(m_pTable->GetTableName())+5, m_cMaxTableName);
|
|
pwszTableName = BuildInvalidName(m, m_pTable->GetTableName(), m_pwszInvalidTableChars);
|
|
TableID.uName.pwszName = pwszTableName;
|
|
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADTABLEID);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(pwszTableName);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID provides the name of an existing table => DB_E_DUPLICATETABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_25()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITableDefinition, NULL, &TableID,
|
|
cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_DUPLICATETABLEID);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc valid riid and NULL ppRowset => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_26()
|
|
{
|
|
TBEGIN
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITableDefinition, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL, &pTableID, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid column name => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_27()
|
|
{
|
|
TBEGIN
|
|
WCHAR *pwszColName = NULL;
|
|
size_t n, m;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// create an invalid column name
|
|
m = min(n=wcslen(rgColumnDesc[0].dbcid.uName.pwszName)+5, m_cMaxColName);
|
|
if (DBKIND_NAME == rgColumnDesc[0].dbcid.eKind)
|
|
pwszColName = rgColumnDesc[0].dbcid.uName.pwszName;
|
|
else
|
|
pwszColName = wcsDuplicate(L"ColumnName");
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = BuildInvalidName(m,
|
|
pwszColName, m_pwszInvalidColChars);
|
|
SAFE_FREE(pwszColName);
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid type name for a column (NULL, empty or inexistent
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_28()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// build the column type name
|
|
SAFE_FREE(rgColumnDesc[0].pwszTypeName);
|
|
|
|
odtLog << "NULL type name\n";
|
|
rgColumnDesc[0].pwszTypeName = NULL;
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
|
|
// verify empty string (bug 26380, empty string for type name should be equivalent to specifying a NULL pointer)
|
|
odtLog << "empty type name for a column\n";
|
|
rgColumnDesc[0].pwszTypeName = wcsDuplicate(L"");
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
|
|
rgColumnDesc[0].pwszTypeName = wcsDuplicate(L"Pay a trip to Europe");
|
|
odtLog << "invalid type name (" << rgColumnDesc[0].pwszTypeName <<")\n";
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADTYPE);
|
|
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid wType for a column => DB_E_BADTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_29()
|
|
{
|
|
TBEGIN
|
|
DBTYPE wInvalidType = 0xffff;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
PROVIDER_FREE(rgColumnDesc[0].pwszTypeName);
|
|
rgColumnDesc[0].pwszTypeName = NULL;
|
|
rgColumnDesc[0].wType = wInvalidType;
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADTYPE);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc wType and pswzTypeName mismatch in a column description => DB_E_BADTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_30()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set an invalid wType
|
|
TESTC_PROVIDER(cColumnDesc >= 7);
|
|
|
|
// each column was assigned a different type; try to mismatch a pwszTypeName and wType for the first col
|
|
PROVIDER_FREE(rgColumnDesc[0].pwszTypeName);
|
|
rgColumnDesc[0].pwszTypeName = rgColumnDesc[7].pwszTypeName;
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADTYPE);
|
|
|
|
CLEANUP:
|
|
if (cColumnDesc > 1)
|
|
rgColumnDesc[0].pwszTypeName = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc not null pTypeInfo => DB_E_BADTYPE (for the time being
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_31()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set a not NULL pTypeInfo
|
|
rgColumnDesc[0].pTypeInfo = (ITypeInfo*)pITableDefinition();
|
|
|
|
TEST2C_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), E_NOINTERFACE, DB_E_BADTYPE);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc duplicate column identifiers => DB_E_DUPLICATECOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_32()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set an invalid wType
|
|
TESTC_PROVIDER(2 < cColumnDesc);
|
|
|
|
// each column was assigned a different type; try to mismatch a pwszTypeName and wType for the first col
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE);
|
|
DuplicateDBID(rgColumnDesc[1].dbcid, &rgColumnDesc[0].dbcid);
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_DUPLICATECOLUMNID);
|
|
|
|
CLEANUP:
|
|
memset(&rgColumnDesc[0].dbcid, 0, sizeof(DBID));
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc improper eKind value in a DBID => DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_33()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set improper eKind in a column DBID
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE);
|
|
rgColumnDesc[0].dbcid.eKind = INVALID_DBKIND;
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid property value on column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_34()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
LONG lValue = 12;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set improper value (different type than required) for a property value of a column
|
|
// DBPROPOPTIONS_REQUIRED
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSet);
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], NUMELEM(rgProp), rgProp, DBPROPSET_COLUMN)
|
|
FILL_PROP(rgProp[0], DBPROP_COL_UNIQUE, DBTYPE_I4, V_I4, lValue, DBPROPOPTIONS_REQUIRED)
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_ERRORSOCCURRED);
|
|
|
|
// set improper value (different type) for a column DBPROPOPTIONS_OPTIONAL
|
|
// try to set the property value of the rowset trough a column
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSet);
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], NUMELEM(rgProp), rgProp, DBPROPSET_COLUMN)
|
|
FILL_PROP(rgProp[0], DBPROP_COL_UNIQUE, DBTYPE_I4, V_I4, lValue, DBPROPOPTIONS_OPTIONAL)
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_S_ERRORSOCCURRED);
|
|
|
|
// try to set a rowset property through a column, DBPROPOPTIONS_REQUIRED
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSet);
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], NUMELEM(rgProp), rgProp, DBPROPSET_ROWSET)
|
|
FILL_PROP(rgProp[0], DBPROP_BOOKMARKS, DBTYPE_I4, V_I4, lValue, DBPROPOPTIONS_REQUIRED)
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_ERRORSOCCURRED);
|
|
|
|
// try to set a rowset property through a column, DBPROPOPTIONS_OPTIONAL
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSet);
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], NUMELEM(rgProp), rgProp, DBPROPSET_ROWSET)
|
|
FILL_PROP(rgProp[0], DBPROP_BOOKMARKS, DBTYPE_I4, V_I4, lValue, DBPROPOPTIONS_OPTIONAL)
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_S_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid column precision => DB_E_BADPRECISION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_35()
|
|
{
|
|
TBEGIN
|
|
const int n=8;
|
|
BYTE testValues[n];
|
|
HRESULT testResult[n]={S_OK, S_OK, S_OK, S_OK, S_OK, S_OK, DB_E_BADPRECISION, DB_E_BADPRECISION};
|
|
CCol Col;
|
|
ULONG cPrecision;
|
|
DBORDINAL i;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
testValues[0] = 0;
|
|
testValues[1] = 1;
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
Col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
ASSERT(0 == wcscmp(Col.GetProviderTypeName(), GetColumnTypeName(&rgColumnDesc[i])));
|
|
|
|
if (rgColumnDesc[i].wType == DBTYPE_NUMERIC)
|
|
testResult[0] = DB_E_BADPRECISION;
|
|
else
|
|
testResult[0] = S_OK;
|
|
|
|
testResult[6] = S_OK;
|
|
testResult[7] = S_OK;
|
|
if (rgColumnDesc[i].wType == DBTYPE_NUMERIC)
|
|
{
|
|
testResult[6] = DB_E_BADPRECISION;
|
|
testResult[7] = DB_E_BADPRECISION;
|
|
|
|
}
|
|
testValues[2] = (BYTE)(Col.GetPrecision()/3);
|
|
testValues[3] = (BYTE)(2*Col.GetPrecision()/3);
|
|
testValues[4] = (BYTE)Col.GetPrecision()-1;
|
|
testValues[5] = (BYTE)Col.GetPrecision();
|
|
testValues[6] = (BYTE)Col.GetPrecision()+1;
|
|
testValues[7] = (BYTE)Col.GetPrecision()+10;
|
|
odtLog << rgColumnDesc[i].pwszTypeName <<" ("
|
|
<< rgColumnDesc[i].dbcid.uName.pwszName << ") max precision =" << testValues[5] << "\n";
|
|
odtLog << "\t" << "precisions tested :";
|
|
for (cPrecision=0; cPrecision<n; cPrecision++)
|
|
odtLog << "\t" << (ULONG)testValues[cPrecision];
|
|
odtLog << "\n";
|
|
|
|
for (cPrecision=0; cPrecision<n; cPrecision++)
|
|
{
|
|
rgColumnDesc[i].bPrecision = (BYTE)testValues[cPrecision];
|
|
rgColumnDesc[i].ulColumnSize = 0;
|
|
rgColumnDesc[i].bScale = 0;
|
|
|
|
if (!CHECK(CCNDropTable(NULL, 1, &rgColumnDesc[i], IID_IRowset, 0, NULL), testResult[cPrecision]))
|
|
{
|
|
odtLog << "Error for precision " << testValues[cPrecision] << "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid scale on column => DB_E_BADSCALE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_36()
|
|
{
|
|
TBEGIN
|
|
const int n=7;
|
|
BYTE testValues[n];
|
|
HRESULT testResult[n]={S_OK, S_OK, S_OK, S_OK, S_OK, DB_E_BADSCALE, DB_E_BADSCALE};
|
|
CCol Col;
|
|
ULONG cScale, m;
|
|
DBORDINAL i;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
testValues[0] = 0;
|
|
testValues[1] = 1;
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
Col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
ASSERT(0 == wcscmp(Col.GetProviderTypeName(), GetColumnTypeName(&rgColumnDesc[i])));
|
|
|
|
odtLog << rgColumnDesc[i].pwszTypeName << "\n";
|
|
testResult[0] = S_OK;
|
|
testResult[1] = S_OK;
|
|
testValues[0] = 0;
|
|
testValues[1] = 1;
|
|
testValues[2] = 100;
|
|
testValues[3] = (BYTE)Col.GetPrecision()+1;
|
|
m = 4;
|
|
if ((rgColumnDesc[i].wType == DBTYPE_NUMERIC) || (rgColumnDesc[i].wType == DBTYPE_DECIMAL))
|
|
{
|
|
m = 7;
|
|
if (Col.GetMinScale()>0)
|
|
{
|
|
testResult[0] = DB_E_BADSCALE;
|
|
testResult[1] = DB_E_BADSCALE;
|
|
}
|
|
testResult[4] = S_OK;
|
|
testValues[1] = (BYTE)max(Col.GetMinScale()-1, 0);
|
|
testValues[2] = (BYTE)Col.GetMinScale();
|
|
testValues[3] = (BYTE)((Col.GetMinScale()+Col.GetMaxScale())/2);
|
|
testValues[4] = (BYTE)Col.GetMaxScale();
|
|
testValues[5] = (BYTE)Col.GetMaxScale()+1;
|
|
testValues[6] = (BYTE)Col.GetMaxScale();
|
|
// tests
|
|
for (cScale=0; cScale<m; cScale++)
|
|
{
|
|
rgColumnDesc[i].bScale = (BYTE)testValues[cScale];
|
|
if (cScale+1 == m)
|
|
{
|
|
rgColumnDesc[i].bPrecision = max(1, Col.GetMaxScale()-2);
|
|
odtLog << "\nprecision: " << rgColumnDesc[i].bPrecision
|
|
<< ", scale: " << testValues[cScale] <<"\n";
|
|
}
|
|
else
|
|
odtLog << "\t" << testValues[cScale];
|
|
|
|
if (!CHECK(CCNDropTable(NULL, 1, &rgColumnDesc[i], IID_IRowset, 0, NULL), testResult[cScale]))
|
|
{
|
|
odtLog << "Error for scale " << testValues[cScale] << "\n";
|
|
}
|
|
}
|
|
odtLog << "\n";
|
|
}
|
|
else
|
|
{
|
|
testResult[4] = S_OK;
|
|
for (cScale=0; cScale<m; cScale++)
|
|
{
|
|
rgColumnDesc[i].bScale = (BYTE)testValues[cScale];
|
|
if (cScale+1 == m)
|
|
rgColumnDesc[cScale].bPrecision = Col.GetMaxScale()-1;
|
|
|
|
if (!CHECK(CCNDropTable(NULL, 1, &rgColumnDesc[i],
|
|
IID_IRowset, 0, NULL), testResult[cScale]))
|
|
{
|
|
odtLog << "Error for scale " << testValues[cScale] << "\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc col prop is not in the Column, Rowset or Table property group and dwOption is DBPROP_SETIFCHEAP => DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_37()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set a column property that doesn't belong to the column, rowset or table propriety group
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSet);
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], NUMELEM(rgProp), rgProp, DBPROPSET_DBINIT)
|
|
FILL_PROP(rgProp[0], DBPROP_AUTH_PASSWORD, DBTYPE_BSTR, V_BSTR,
|
|
SysAllocString(L"passwd"), DBPROPOPTIONS_OPTIONAL)
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_S_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
SysFreeString(V_BSTR(&rgProp[0].vValue));
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(38)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc col prop is not in the Column, Rowset or Table property group and dwOption is DBPROP_REQUIRED => DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_38()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set a column property ID that is not valid
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSet);
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], NUMELEM(rgProp), rgProp, DBPROPSET_DBINIT)
|
|
FILL_PROP(rgProp[0], DBPROP_AUTH_PASSWORD, DBTYPE_BSTR, V_BSTR,
|
|
SysAllocString(L"passwd"), DBPROPOPTIONS_REQUIRED)
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
SysFreeString(V_BSTR(&rgProp[0].vValue));
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(39)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid propID for a column propriety
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_39()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// set an inexistent column property with DBPROPOPTIONS_OPTIONAL
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSet);
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], 1, rgProp, DBPROPSET_COLUMN)
|
|
FILL_PROP(rgProp[0], 0xffff, DBTYPE_I4, V_I4, 42, DBPROPOPTIONS_OPTIONAL)
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_S_ERRORSOCCURRED);
|
|
|
|
// set an inexistent column property with DBPROPOPTIONS_REQUIRED
|
|
rgColumnDesc[0].cPropertySets = NUMELEM(rgPropSet);
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], 1, rgProp, DBPROPSET_COLUMN)
|
|
FILL_PROP(rgProp[0], 0xffff, DBTYPE_I4, V_I4, 42, DBPROPOPTIONS_REQUIRED)
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(40)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc colid in DBPROP of a column property is ignored
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_40()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPID rgPropID[] = { DBPROP_COL_AUTOINCREMENT, DBPROP_COL_NULLABLE};
|
|
ULONG i;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
|
|
// set a column property that is not ...
|
|
for (i=0; i<NUMELEM(rgPropID); i++)
|
|
{
|
|
if (SettableProperty(rgPropID[i], DBPROPSET_COLUMN))
|
|
break;
|
|
}
|
|
TESTC_PROVIDER(i<NUMELEM(rgPropID));
|
|
|
|
rgColumnDesc[0].cPropertySets = 1;
|
|
rgColumnDesc[0].rgPropertySets = rgPropSet;
|
|
FILL_PROP_SET(rgPropSet[0], 1, rgProp, DBPROPSET_COLUMN)
|
|
FILL_PROP(rgProp[0], rgPropID[i], DBTYPE_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL)
|
|
|
|
// set colID to a value different from DB_NULLID
|
|
rgProp[0].colid.eKind = DBKIND_NAME;
|
|
rgProp[0].colid.uName.pwszName = wcsDuplicate(L"someColumn");
|
|
|
|
// check colid is ignored for the column property
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
COMPARE(DBPROPSTATUS_OK == rgProp[0].dwStatus, TRUE);
|
|
|
|
// check colid is ignored for the column property
|
|
rgProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
COMPARE(DBPROPSTATUS_OK == rgProp[0].dwStatus, TRUE);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgProp[0].colid.uName.pwszName);
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(41)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_41()
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBID *pTableID = NULL;
|
|
DBPROPSET *rgPropSet = NULL;
|
|
ULONG cPropSet = 0;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
BOOL fAbortPreserve = TRUE;
|
|
ULONG cReadPropSet = 0;
|
|
DBPROPSET *rgReadPropSet = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT vSupportedTxnDDL;
|
|
HRESULT hr;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// if possible, prepare to ask DBPROP_ABORTPRESERVE to be set to VARIANT_FALSE
|
|
if (SettableProperty(DBPROP_ABORTPRESERVE, DBPROPSET_ROWSET))
|
|
{
|
|
::SetProperty(DBPROP_ABORTPRESERVE, DBPROPSET_ROWSET, &cPropSet, &rgPropSet,
|
|
(LPVOID)VARIANT_FALSE, VT_BOOL, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
}
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(hr = m_pITableDefinition->CreateTable(NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(hr = CreateAndCheckTable(m_pITableDefinition, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc, IID_IRowsetInfo,
|
|
cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
CHECK(hr = m_pITableDefinition->CreateTable(NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
if (pIRowsetInfo)
|
|
fAbortPreserve = GetProperty(DBPROP_ABORTPRESERVE, DBPROPSET_ROWSET, pIRowsetInfo, VARIANT_TRUE);
|
|
// abort retaining
|
|
CHECK(pITransactionLocal->Abort(NULL, TRUE, FALSE), S_OK);
|
|
// check that it is retaining (another transaction is available)
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
}
|
|
|
|
// abort retaining and check that the table doesn't exist anymore
|
|
CHECK(m_hr = m_pTable->DoesTableExist(pTableID, &fExists), S_OK);
|
|
COMPARE(fExists, DBPROPVAL_TC_DDL_IGNORE == vSupportedTxnDDL.lVal
|
|
|| DBPROPVAL_TC_DDL_COMMIT == vSupportedTxnDDL.lVal);
|
|
if (fExists)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
}
|
|
|
|
// test zombie rowset
|
|
if (pIRowsetInfo)
|
|
TESTC_(pIRowsetInfo->GetProperties(0, NULL, &cReadPropSet, &rgReadPropSet), fAbortPreserve? S_OK: E_UNEXPECTED);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
ReleaseDBID(pTableID);
|
|
FreeProperties( &cPropSet, &rgPropSet);
|
|
FreeProperties( &cReadPropSet, &rgReadPropSet);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(42)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort without retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_42()
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBID *pTableID = NULL;
|
|
DBPROPSET *rgPropSet = NULL;
|
|
ULONG cPropSet = 0;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
BOOL fAbortPreserve = TRUE;
|
|
ULONG cReadPropSet = 0;
|
|
DBPROPSET *rgReadPropSet = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// if possible, prepare to ask DBPROP_ABORTPRESERVE to be set to VARIANT_FALSE
|
|
if (SettableProperty(DBPROP_ABORTPRESERVE, DBPROPSET_ROWSET))
|
|
{
|
|
::SetProperty(DBPROP_ABORTPRESERVE, DBPROPSET_ROWSET, &cPropSet, &rgPropSet,
|
|
(LPVOID)VARIANT_FALSE, VT_BOOL, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
}
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->CreateTable(NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(CreateAndCheckTable(m_pITableDefinition, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc, IID_IRowsetInfo,
|
|
cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
CHECK(m_hr = m_pITableDefinition->CreateTable(NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
fAbortPreserve = GetProperty(DBPROP_ABORTPRESERVE, DBPROPSET_ROWSET, pIRowsetInfo, VARIANT_TRUE);
|
|
// abort non retaining
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
// check that it is retaining (another transaction is available)
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE),
|
|
FAILED(m_hr)? S_OK : XACT_E_NOTRANSACTION);
|
|
}
|
|
|
|
// abort retaining and check that the table doesn't exist anymore
|
|
CHECK(m_hr = m_pTable->DoesTableExist(pTableID, &fExists), S_OK);
|
|
COMPARE(fExists, DBPROPVAL_TC_DDL_IGNORE == vSupportedTxnDDL.lVal
|
|
|| DBPROPVAL_TC_DDL_COMMIT == vSupportedTxnDDL.lVal);
|
|
if (fExists)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
}
|
|
|
|
// test zombie rowset
|
|
TESTC_(pIRowsetInfo->GetProperties(0, NULL, &cReadPropSet, &rgReadPropSet), fAbortPreserve? S_OK: E_UNEXPECTED);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
ReleaseDBID(pTableID);
|
|
FreeProperties( &cPropSet, &rgPropSet);
|
|
FreeProperties(&cReadPropSet, &rgReadPropSet);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(43)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_43()
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBID *pTableID = NULL;
|
|
DBPROPSET *rgPropSet = NULL;
|
|
ULONG cPropSet = 0;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
BOOL fCommitPreserve = TRUE;
|
|
ULONG cReadPropSet = 0;
|
|
DBPROPSET *rgReadPropSet = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// if possible, prepare to ask DBPROP_ABORTPRESERVE to be set to VARIANT_FALSE
|
|
if (SettableProperty(DBPROP_COMMITPRESERVE, DBPROPSET_ROWSET))
|
|
{
|
|
::SetProperty(DBPROP_COMMITPRESERVE, DBPROPSET_ROWSET, &cPropSet, &rgPropSet,
|
|
(LPVOID)VARIANT_FALSE, VT_BOOL, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
}
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->CreateTable(NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(CreateAndCheckTable(m_pITableDefinition, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc, IID_IRowsetInfo,
|
|
cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
CHECK(m_hr = m_pITableDefinition->CreateTable(NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
fCommitPreserve = GetProperty(DBPROP_COMMITPRESERVE, DBPROPSET_ROWSET, pIRowsetInfo, VARIANT_TRUE);
|
|
// commit retaining
|
|
CHECK(m_hr = pITransactionLocal->Commit(TRUE, 0, 0), S_OK);
|
|
// check that it is retaining (another transaction is available)
|
|
CHECK(m_hr = pITransactionLocal->Abort(NULL, FALSE, FALSE), S_OK);
|
|
}
|
|
|
|
// abort retaining and check that the table doesn't exist anymore
|
|
CHECK(m_hr = m_pTable->DoesTableExist(pTableID, &fExists), S_OK);
|
|
COMPARE(fExists, DBPROPVAL_TC_DML != vSupportedTxnDDL.lVal);
|
|
if (fExists)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
}
|
|
|
|
// test zombie rowset
|
|
TESTC_(pIRowsetInfo->GetProperties(0, NULL, &cReadPropSet, &rgReadPropSet), fCommitPreserve? S_OK: E_UNEXPECTED);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
DropTableAndCheck(pTableID);
|
|
ReleaseDBID(pTableID);
|
|
FreeProperties( &cPropSet, &rgPropSet);
|
|
FreeProperties(&cReadPropSet, &rgReadPropSet);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(44)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit non-retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_44()
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
ITransactionLocal *pITransactionLocal = NULL;
|
|
DBID *pTableID = NULL;
|
|
DBPROPSET *rgPropSet = NULL;
|
|
ULONG cPropSet = 0;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
BOOL fCommitPreserve = TRUE;
|
|
ULONG cReadPropSet = 0;
|
|
DBPROPSET *rgReadPropSet = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pITableDefinition, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
// what values should we accept?
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(StartTransaction(pITransactionLocal), S_OK);
|
|
|
|
// if possible, prepare to ask DBPROP_ABORTPRESERVE to be set to VARIANT_FALSE
|
|
if (SettableProperty(DBPROP_COMMITPRESERVE, DBPROPSET_ROWSET))
|
|
{
|
|
::SetProperty(DBPROP_COMMITPRESERVE, DBPROPSET_ROWSET, &cPropSet, &rgPropSet,
|
|
(LPVOID)VARIANT_FALSE, VT_BOOL, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
}
|
|
|
|
switch(vSupportedTxnDDL.lVal)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(m_hr = m_pITableDefinition->CreateTable(NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(CreateAndCheckTable(m_pITableDefinition, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc, IID_IRowsetInfo,
|
|
cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
// error should be returned
|
|
CHECK(m_hr = m_pITableDefinition->CreateTable(NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, cPropSet, rgPropSet, &pTableID,
|
|
(IUnknown**)&pIRowsetInfo), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
fCommitPreserve = GetProperty(DBPROP_COMMITPRESERVE, DBPROPSET_ROWSET, pIRowsetInfo, VARIANT_TRUE);
|
|
// commit non retaining
|
|
CHECK(m_hr = pITransactionLocal->Commit(FALSE, 0, 0), S_OK);
|
|
// check that it is retaining (another transaction is available)
|
|
CHECK(pITransactionLocal->Abort(NULL, FALSE, FALSE),
|
|
FAILED(m_hr)? S_OK: XACT_E_NOTRANSACTION);
|
|
}
|
|
|
|
// abort retaining and check that the table doesn't exist anymore
|
|
CHECK(m_hr = m_pTable->DoesTableExist(pTableID, &fExists), S_OK);
|
|
COMPARE(fExists, DBPROPVAL_TC_DML != vSupportedTxnDDL.lVal);
|
|
if (fExists)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// test zombie rowset
|
|
TESTC_(pIRowsetInfo->GetProperties(0, NULL, &cReadPropSet, &rgReadPropSet), fCommitPreserve? S_OK: E_UNEXPECTED);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
DropTableAndCheck(pTableID);
|
|
ReleaseDBID(pTableID);
|
|
FreeProperties( &cPropSet, &rgPropSet);
|
|
FreeProperties(&cReadPropSet, &rgReadPropSet);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(45)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Autoincrementable columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_45()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
HRESULT resA, resB;
|
|
CCol col;
|
|
BOOL fReadWriteAutoInc;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
ULONG cPropSet, cProp;
|
|
|
|
fReadWriteAutoInc = (GetPropInfoFlags(DBPROP_COL_AUTOINCREMENT, DBPROPSET_COLUMN,
|
|
m_pThisTestModule->m_pIUnknown, DATASOURCE_INTERFACE) & DBPROPFLAGS_WRITE);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
//SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
|
|
// try all data types
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << "Type " << GetColumnTypeName(&rgColumnDesc[i]) << "\n";
|
|
// try to create a table in which column rgColumnDesc[i].pwszTypeName is:
|
|
// a) autoincrementable
|
|
// b) not autoincrementable
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
resA = col.CanAutoInc()? S_OK: DB_E_ERRORSOCCURRED;
|
|
resB = !col.CanAutoInc() || fReadWriteAutoInc? S_OK : DB_E_ERRORSOCCURRED;
|
|
|
|
// create a table with an autoincrementable column
|
|
rgColumnDesc[i].bScale = 0;
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_AUTOINCREMENT,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED, DB_NULLID,
|
|
DBPROPSET_COLUMN, &cPropSet, &cProp);
|
|
|
|
CHECK(hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
0, NULL), resA);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
COMPARE(rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus, DBPROPSTATUS_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
|
|
if (!fReadWriteAutoInc && !col.CanAutoInc())
|
|
COMPARE(rgColumnDesc[i].rgPropertySets[0].rgProperties[0].dwStatus, DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
|
|
odtLog << ((hr == S_OK) ? "\tcolumn added for DBPROPCOL_AUTOINCREMENT set to VARIANT_TRUE\n":
|
|
"\tcolumn NOT added for DBPROPCOL_AUTOINCREMENT set to VARIANT_TRUE\n");
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
|
|
// create a table with a column property value to VARIANT_FALSE for DBPROP_COL_AUTOINCREMENT
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_AUTOINCREMENT,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_REQUIRED, DB_NULLID,
|
|
DBPROPSET_COLUMN, &cPropSet, &cProp);
|
|
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), resB);
|
|
|
|
odtLog << ((S_OK == hr) ? "\tcolumn added for DBPROPCOL_AUTOINCREMENT set to VARIANT_FALSE\n":
|
|
"\tcolumn NOT added for DBPROPCOL_AUTOINCREMENT set to VARIANT_FALSE\n");
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(46)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Default values
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_46()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
CCol col;
|
|
VARIANT value;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
BOOL fSettable = TRUE;
|
|
BOOL fSupported = TRUE;
|
|
HRESULT hr;
|
|
ULONG cPropSet, cProp;
|
|
|
|
if (!SupportedProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
{
|
|
fSettable = FALSE;
|
|
fSupported = FALSE;
|
|
}
|
|
else
|
|
if (!SettableProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
fSettable = FALSE;
|
|
|
|
pTable->CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << "Type " << GetColumnTypeName(&rgColumnDesc[i]) << "\n";
|
|
|
|
// try to create a table in which column rgColumnDesc[i].pwszTypeName has a default value
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
|
|
// create a table with a default value column
|
|
VariantInit(&value);
|
|
GetDefaultValue(&rgColumnDesc[i], &value, pTable);
|
|
SetDefaultProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
&value, DBPROPOPTIONS_REQUIRED, DB_NULLID, DBPROPSET_COLUMN, &cPropSet, &cProp); // might be not supported
|
|
VariantClear(&value);
|
|
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
COMPARE(rgColumnDesc[i].rgPropertySets[0].rgProperties[0].dwStatus, DBPROPSTATUS_OK);
|
|
}
|
|
else
|
|
{
|
|
odtLog << "Failed on creating a table with a DBPROP_COL_DEFAULT property value set for this type.\n";
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
|
|
if (!fSupported)
|
|
{
|
|
COMPARE(rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus, DBPROPSTATUS_NOTSUPPORTED);
|
|
}
|
|
else
|
|
if (!fSettable)
|
|
{
|
|
COMPARE(rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus, DBPROPSTATUS_BADVALUE);
|
|
}
|
|
else
|
|
COMPARE(rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus, DBPROPSTATUS_BADVALUE);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
delete pTable;
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(47)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Column descriptions
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_47()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
CCol col;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
//SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << "Type " << GetColumnTypeName(&rgColumnDesc[i]) << "\n";
|
|
// try to create a table in which column rgColumnDesc[i].pwszTypeName has a description
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
|
|
// create a table with a described column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_DESCRIPTION,
|
|
VT_BSTR, (LPVOID)L"description");
|
|
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL);
|
|
|
|
if (S_OK != hr && !CHECK(hr, DB_S_ERRORSOCCURRED))
|
|
{
|
|
odtLog << "Could not create a table with DBPROP_COL_DESCRIPTION property value set for this type.\n";
|
|
}
|
|
else
|
|
{
|
|
if (DB_S_ERRORSOCCURRED == hr)
|
|
odtLog << "DB_S_ERRORSOCCURRED\n";
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
}
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(48)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Variable length columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_48()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
VARIANT value;
|
|
CCol col;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
value.vt = VT_BOOL;
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
//SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
if ( DBTYPE_STR != rgColumnDesc[i].wType
|
|
&& DBTYPE_WSTR != rgColumnDesc[i].wType
|
|
&& DBTYPE_BYTES != rgColumnDesc[i].wType)
|
|
continue;
|
|
|
|
odtLog << "Type " << rgColumnDesc[i].pwszTypeName << "\n";
|
|
// try to create a table in which column rgColumnDesc[i].pwszTypeName is:
|
|
// a) fixed length
|
|
// b) variable length
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
|
|
// create a table with an fixed length column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_FIXEDLENGTH,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE);
|
|
odtLog << "\ttry to create a table with a fixed length column of type "
|
|
<< rgColumnDesc[i].pwszTypeName << "\n";
|
|
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL);
|
|
|
|
if (S_OK != hr && !CHECK(hr, DB_S_ERRORSOCCURRED))
|
|
{
|
|
odtLog << "\t\tProblems in creating a table with DBPROP_COL_FIXEDLENGTH property value set to VARIANT_TRUE for this column.\n";
|
|
}
|
|
FreeProperties( &rgColumnDesc[i].cPropertySets, &rgColumnDesc[i].rgPropertySets);
|
|
|
|
// create a table with a column property value set to VARIANT_FALSE for DBPROP_COL_FIXEDLENGTH
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_FIXEDLENGTH,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE);
|
|
odtLog << "\ttry to create a table with a variable length column of type "
|
|
<< rgColumnDesc[i].pwszTypeName << "\n";
|
|
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL);
|
|
|
|
if (S_OK != hr && !CHECK(hr, DB_S_ERRORSOCCURRED))
|
|
{
|
|
odtLog << "\t\tCould not create a table with DBPROP_COL_FIXEDLENGTH property value set to VARIANT_FALSE for this column.\n";
|
|
}
|
|
|
|
FreeProperties( &rgColumnDesc[i].cPropertySets, &rgColumnDesc[i].rgPropertySets);
|
|
}
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(49)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Nullable/non nullable columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_49()
|
|
{
|
|
BOOL fTestRes = TEST_PASS;
|
|
DBORDINAL i;
|
|
CCol col;
|
|
VARIANT defval;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CTable *pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
HRESULT hExpRes = S_OK;
|
|
BOOL fSettable = TRUE;
|
|
BOOL fSupported = TRUE;
|
|
DBPROP *pPropDefault = NULL;
|
|
DBPROPSTATUS ulStatus;
|
|
ULONG cPropSet, cProp;
|
|
|
|
if (!SupportedProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN))
|
|
{
|
|
hExpRes = DB_S_ERRORSOCCURRED;
|
|
fSettable = FALSE;
|
|
fSupported = FALSE;
|
|
}
|
|
else
|
|
if (!SettableProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN))
|
|
fSettable = FALSE;
|
|
|
|
pTable->CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
//SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << "Type " << GetColumnTypeName(&rgColumnDesc[i]);
|
|
// try to create a table in which column i is:
|
|
// a) nullable
|
|
// b) not nullable
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
switch (col.GetNullable())
|
|
{
|
|
case 0:
|
|
odtLog << " (not nullable)\n";
|
|
break;
|
|
case 1:
|
|
odtLog << " (NULLable)\n";
|
|
break;
|
|
default:
|
|
odtLog << "\n";
|
|
}
|
|
|
|
// create a table with a nullable column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED, DB_NULLID, DBPROPSET_COLUMN,
|
|
&cPropSet, &cProp);
|
|
|
|
odtLog << "\tcreate table with a nullable column: ";
|
|
// create a table with a column property value set to VARIANT_TRUE for DBPROP_COL_NULLABLE
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL);
|
|
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus;
|
|
if ( (S_OK == hr && !COMPARE(ulStatus, DBPROPSTATUS_OK))
|
|
|| (!fSupported && !COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED))
|
|
|| (S_OK != hr && fSettable && !COMPARE(ulStatus, DBPROPSTATUS_BADVALUE))
|
|
|| (S_OK != hr && !fSettable && !COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE))
|
|
|| (!fSupported && !CHECK(hr, DB_E_ERRORSOCCURRED))
|
|
|| (S_OK != hr && !CHECK(hr, DB_E_ERRORSOCCURRED)))
|
|
fTestRes = TEST_FAIL;
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
|
|
switch (col.GetNullable())
|
|
{
|
|
case 0:
|
|
if (!CHECK(hr, DB_E_ERRORSOCCURRED))
|
|
fTestRes = TEST_FAIL;
|
|
break;
|
|
case 1:
|
|
if (!CHECK(hr, S_OK))
|
|
fTestRes = TEST_FAIL;
|
|
break;
|
|
case -1:
|
|
if (S_OK != hr && !CHECK(hr, DB_E_ERRORSOCCURRED))
|
|
fTestRes = TEST_FAIL;
|
|
break;
|
|
default:
|
|
ASSERT(FALSE);
|
|
break;
|
|
}
|
|
|
|
odtLog << ((SUCCEEDED(hr)) ? "CREATED\n" : "INSUCCESS\n");
|
|
|
|
// create a table with a column property value set to VARIANT_FALSE for DBPROP_COL_NULLABLE
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_REQUIRED, DB_NULLID, DBPROPSET_COLUMN,
|
|
&cPropSet, &cProp);
|
|
if (SettableProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
{
|
|
VariantInit(&defval);
|
|
GetDefaultValue(&rgColumnDesc[i], &defval, pTable);
|
|
if (SettableProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
SetDefaultProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets,
|
|
&defval, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&defval);
|
|
}
|
|
|
|
odtLog << "\tcreate table with a not nullable column\n";
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL);
|
|
|
|
ulStatus = rgColumnDesc[i].rgPropertySets[cPropSet].rgProperties[cProp].dwStatus;
|
|
FindProperty(
|
|
DBPROP_COL_DEFAULT,
|
|
DBPROPSET_COLUMN,
|
|
rgColumnDesc[i].cPropertySets,
|
|
rgColumnDesc[i].rgPropertySets,
|
|
&pPropDefault
|
|
);
|
|
|
|
if ( (!pPropDefault || DBPROPSTATUS_OK == pPropDefault->dwStatus)
|
|
&& ( (S_OK == hr && !COMPARE(ulStatus, DBPROPSTATUS_OK))
|
|
|| (!fSupported && !COMPARE(ulStatus, DBPROPSTATUS_NOTSUPPORTED))
|
|
|| (S_OK != hr && fSettable && !COMPARE(ulStatus, DBPROPSTATUS_BADVALUE))
|
|
|| (S_OK != hr && !fSettable && !COMPARE(ulStatus, DBPROPSTATUS_NOTSETTABLE))
|
|
|| (!fSupported && !CHECK(hr, DB_E_ERRORSOCCURRED))
|
|
|| (S_OK != hr && !CHECK(hr, DB_E_ERRORSOCCURRED))))
|
|
fTestRes = TEST_FAIL;
|
|
|
|
if (FAILED(hr))
|
|
odtLog << "Could not create a table with DBPROP_COL_NULLABLE property value set to VARIANT_FALSE.\n";
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
}
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
delete pTable;
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(50)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_50()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
CCol col;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
HRESULT hExpRes = S_OK;
|
|
|
|
if (!SupportedProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN))
|
|
hExpRes = DB_S_ERRORSOCCURRED;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
// this is to prevent SQL Server limiting the size of
|
|
// the index it creates for primary key or unique columns
|
|
SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << "Type " << GetColumnTypeName(&rgColumnDesc[i]) << "\n";
|
|
// try to create a table in which column _rgColumnDesc[i].pwszTypeName is:
|
|
// a) primary key
|
|
// b) not primary key
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
|
|
// create a table with an primary key column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_PRIMARYKEY,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_OPTIONAL);
|
|
|
|
if (S_OK != (hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL)))
|
|
{
|
|
CHECK(hr, DB_S_ERRORSOCCURRED);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
|
|
// create a table with a column property value set to VARIANT_FALSE for DBPROP_COL_PRIMARYKEY
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_PRIMARYKEY,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL);
|
|
|
|
if (1 != col.GetNullable())
|
|
hExpRes = DB_S_ERRORSOCCURRED;
|
|
|
|
if (S_OK != (hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL)))
|
|
{
|
|
CHECK(hr, DB_S_ERRORSOCCURRED);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
}
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(51)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Unique columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_51()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i;
|
|
CCol col;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
BOOL fSupported = FALSE;
|
|
|
|
fSupported = SupportedProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
// this is to prevent SQL Server limiting the size of
|
|
// the index it creates for primary key or unique columns
|
|
SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
|
|
for (i=0; i<cColumnDesc; i++)
|
|
{
|
|
odtLog << "Type " << GetColumnTypeName(&rgColumnDesc[i]) << "\n";
|
|
// try to create a table in which column rgColumnDesc[i].pwszTypeName is:
|
|
// a) unique
|
|
// b) non-unique
|
|
// there is no info whether a type can or cannot be unique
|
|
col = GetType(GetColumnTypeName(&rgColumnDesc[i]), rgColumnDesc[i].wType);
|
|
|
|
// create a table with an unique column
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_UNIQUE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL);
|
|
|
|
if (S_OK != hr)
|
|
{
|
|
odtLog << "Could not create a table with DBPROP_COL_UNIQUE property value set to VARIANT_TRUE for this column.\n";
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
}
|
|
else
|
|
{
|
|
COMPARE(fSupported, TRUE);
|
|
}
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
|
|
// create a table with a column property value set to VARIANT_FALSE for DBPROP_COL_UNIQUE
|
|
SetProperty(&rgColumnDesc[i].rgPropertySets, &rgColumnDesc[i].cPropertySets, DBPROP_COL_UNIQUE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE, DBPROPOPTIONS_OPTIONAL);
|
|
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL);
|
|
|
|
if (S_OK != hr)
|
|
{
|
|
odtLog << "Could not create a table with DBPROP_COL_UNIQUE property value set to VARIANT_FALSE for this column.\n";
|
|
CHECK(hr, DB_S_ERRORSOCCURRED);
|
|
}
|
|
else
|
|
{
|
|
COMPARE(fSupported, TRUE);
|
|
}
|
|
|
|
ReleaseAllColumnPropSets(&rgColumnDesc[i], 1);
|
|
}
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(52)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Test conflicting properties
|
|
// a column that is both nullable and primary key
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_52()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN)
|
|
&& SettableProperty(DBPROP_COL_PRIMARYKEY, DBPROPSET_COLUMN));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
//SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
|
|
// create a table with a column showing contradiction in properties
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets, DBPROP_COL_PRIMARYKEY,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets, DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), DB_E_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(53)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and ask for a rowset, setting DBPROP_ABORTPRESERVE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_53()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET *rgPropertySets = NULL;
|
|
ULONG cPropertySets = 0;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
//SetZeroColSize(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_PROVIDER(SupportedProperty(DBPROP_ABORTPRESERVE, DBPROPSET_ROWSET)
|
|
&& SettableProperty(DBPROP_ABORTPRESERVE, DBPROPSET_ROWSET));
|
|
SetProperty(&rgPropertySets, &cPropertySets, DBPROP_ABORTPRESERVE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE, DBPROPOPTIONS_REQUIRED, DB_NULLID, DBPROPSET_ROWSET);
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowsetInfo,
|
|
cPropertySets, rgPropertySets), S_OK);
|
|
|
|
CLEANUP:
|
|
FreeProperties( &cPropertySets, &rgPropertySets);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(54)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inserting rows after table creation, using the resulting rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_54()
|
|
{
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
BOOL fTestRes = TEST_FAIL;
|
|
BOOL fMayWrite;
|
|
DBORDINAL i;
|
|
const ULONG nRows = 10;
|
|
DBID *pTableID = NULL;
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET *rgPropSets = NULL;
|
|
LONG lUpdateInsert = DBPROPVAL_UP_INSERT;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CList <WCHAR*, WCHAR*> ListNativeTemp;
|
|
CList <DBTYPE, DBTYPE> ListDataTypes;
|
|
CTable *pTable = NULL;
|
|
|
|
pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
// get the provider types list
|
|
pTable->CreateColInfo(ListNativeTemp, ListDataTypes, ALLTYPES);
|
|
// build the column description array
|
|
pTable->BuildColumnDescs(&rgColumnDesc);
|
|
cColumnDesc = pTable->CountColumnsOnTable();
|
|
pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
//Need to set DBPROP_UPDATABILITY: InsertRow is supported
|
|
if ( !SupportedProperty(DBPROP_IRowsetChange, DBPROPSET_ROWSET)
|
|
|| !SettableProperty(DBPROP_IRowsetChange, DBPROPSET_ROWSET))
|
|
{
|
|
fTestRes = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
//Need to set DBPROP_UPDATABILITY: InsertRow is supported
|
|
if ( !SupportedProperty(DBPROP_UPDATABILITY, DBPROPSET_ROWSET)
|
|
|| !SettableProperty(DBPROP_UPDATABILITY, DBPROPSET_ROWSET))
|
|
{
|
|
fTestRes = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
::SetProperty( DBPROP_UPDATABILITY, DBPROPSET_ROWSET, &cPropSets, &rgPropSets,
|
|
DBTYPE_I4, (LPVOID)&lUpdateInsert);
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc, IID_IRowsetChange,
|
|
cPropSets, rgPropSets, &pTableID, (IUnknown**)&pIRowsetChange), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
|
|
// find out if one can write to that table
|
|
pTable->SetTableID(*pTableID);
|
|
pTable->MayWrite(&fMayWrite);
|
|
for (i=0; i<nRows; i++)
|
|
{
|
|
m_hr = Insert(0, pIRowsetChange, 0, NULL, pTable);
|
|
if (DB_E_NOTSUPPORTED != m_hr)
|
|
{
|
|
if (!CHECK(m_hr, S_OK))
|
|
fTestRes = TEST_FAIL;
|
|
}
|
|
else
|
|
fTestRes = TEST_SKIPPED;
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
if (pTableID)
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID);
|
|
FreeProperties( &cPropSets, &rgPropSets);
|
|
delete pTable;
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(55)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Delete rows in the created rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_55()
|
|
{
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
IRowset *pIRowset = NULL;
|
|
BOOL fTestRes = TEST_FAIL;
|
|
ULONG i, nSuccess;
|
|
const ULONG nRows = 10;
|
|
const int nProps = 3;
|
|
DBPROPSET rgPropSets[1];
|
|
DBPROP rgProperties[nProps];
|
|
HROW *rghRow = NULL;
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
DBROWSTATUS rgRowStatus[nRows];
|
|
DBID *pTableID = NULL;
|
|
BOOL fMayWrite;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CList <WCHAR*, WCHAR*> ListNativeTemp;
|
|
CList <DBTYPE, DBTYPE> ListDataTypes;
|
|
CTable *pTable = NULL;
|
|
|
|
pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
// get the provider types list
|
|
pTable->CreateColInfo(ListNativeTemp, ListDataTypes, ALLTYPES);
|
|
// build the column description array
|
|
pTable->BuildColumnDescs(&rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc=pTable->CountColumnsOnTable());
|
|
pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProperties), rgProperties, DBPROPSET_ROWSET)
|
|
FILL_PROP(rgProperties[0], DBPROP_IRowsetChange, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL)
|
|
FILL_PROP(rgProperties[1], DBPROP_OWNINSERT, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED)
|
|
FILL_PROP(rgProperties[2], DBPROP_OWNUPDATEDELETE, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL)
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc, IID_IRowsetChange,
|
|
NUMELEM(rgPropSets), rgPropSets, &pTableID, (IUnknown**)&pIRowsetChange), S_OK);
|
|
|
|
pTable->SetTableID(*pTableID);
|
|
pTable->MayWrite(&fMayWrite);
|
|
for (i=0; i<nRows; i++)
|
|
{
|
|
m_hr = Insert(0, pIRowsetChange, 0, NULL, pTable);
|
|
if (DB_E_NOTSUPPORTED == m_hr)
|
|
{
|
|
odtLog << "IRowsetChange->Insert() is not supported\n";
|
|
fTestRes = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
else
|
|
TESTC_(m_hr, S_OK);
|
|
}
|
|
|
|
// get a pointer to IRoewset interface
|
|
if (!VerifyInterface(pIRowsetChange, IID_IRowset, ROWSET_INTERFACE, (IUnknown**)&pIRowset))
|
|
{
|
|
odtLog << "could not get IRowsetChange\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
m_hr = pIRowset->RestartPosition(NULL);
|
|
if (!CHECK(m_hr = pIRowset->GetNextRows(
|
|
0, 0, // hChapter & lRowsOffset
|
|
nRows, // number of rows to be retrieved
|
|
&cRowsObtained, //number of rows actually get
|
|
&rghRow // array of handlers to rows
|
|
), S_OK) || nRows != cRowsObtained)
|
|
{
|
|
odtLog << "insuccess on IRowset::GetNextRows\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
TESTC_(m_hr = pIRowsetChange->DeleteRows(0, cRowsObtained, rghRow, rgRowStatus), S_OK);
|
|
|
|
for (i=nSuccess=0; i<nRows; i++)
|
|
if (DBROWSTATUS_S_OK == rgRowStatus[i])
|
|
nSuccess ++;
|
|
|
|
if (nSuccess != nRows)
|
|
odtLog << "delete succeeded for " << nRows-nSuccess << " rows out of " << nRows << "\n";
|
|
else
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
if (cRowsObtained)
|
|
CHECK(m_hr = pIRowset->ReleaseRows(cRowsObtained, rghRow, NULL, NULL, NULL), S_OK);
|
|
PROVIDER_FREE(rghRow);
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
SAFE_RELEASE(pIRowset);
|
|
if (pTableID)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID);
|
|
}
|
|
delete pTable;
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(56)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Aggregation, ask for IID_IUnknown
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_56()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBID *pTableID = NULL;
|
|
CAggregate Aggregate(m_pIOpenRowset);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TEST2C_(hr = CreateAndCheckTable(m_pITableDefinition, &Aggregate, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IUnknown, 0, NULL, &pTableID, (IUnknown**)&Aggregate.m_pIUnkInner),
|
|
S_OK, DB_E_NOAGGREGATION);
|
|
|
|
TESTC_PROVIDER(S_OK == hr);
|
|
// Verify Aggregation for this rowset...
|
|
TESTC(Aggregate.VerifyAggregationQI(hr, IID_IRowset));
|
|
|
|
|
|
CLEANUP:
|
|
Aggregate.ReleaseInner();
|
|
// checkings, etc
|
|
CHECK(DropTableAndCheck(pTableID), pTableID? S_OK: E_INVALIDARG);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(57)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and ask for a rowset, setting DBPROP_COMMITPRESERVE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_57()
|
|
{
|
|
TBEGIN
|
|
DBPROPID rgPropID=DBPROP_COMMITPRESERVE;
|
|
|
|
COMPARE(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
(struct _GUID*)&IID_IRowsetInfo), TRUE);
|
|
TESTC(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
(struct _GUID*)&IID_IRowsetInfo));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(58)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and ask for a rowset, setting DBPROP_OWNINSERT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_58()
|
|
{
|
|
TBEGIN
|
|
DBPROPID rgPropID=DBPROP_OWNINSERT;
|
|
|
|
COMPARE(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
(struct _GUID*)&IID_IRowsetInfo), TRUE);
|
|
TESTC(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
(struct _GUID*)&IID_IRowsetInfo));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(59)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and ask for a rowset, setting DBPROP_BOOKMARKS
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_59()
|
|
{
|
|
TBEGIN
|
|
DBPROPID rgPropID=DBPROP_BOOKMARKS;
|
|
|
|
COMPARE(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
(struct _GUID*)&IID_IRowsetInfo), TRUE);
|
|
TESTC(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
(struct _GUID*)&IID_IRowsetInfo));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(60)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and ask for a rowset, setting DBPROP_CANHOLDROWS
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_60()
|
|
{
|
|
TBEGIN
|
|
DBPROPID rgPropID=DBPROP_CANHOLDROWS;
|
|
|
|
COMPARE(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
(struct _GUID*)&IID_IRowsetInfo), TRUE);
|
|
TESTC(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
(struct _GUID*)&IID_IRowsetInfo));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(61)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and ask for a rowset, setting DBPROP_MAYWRITECOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_61()
|
|
{
|
|
TBEGIN
|
|
DBPROPID rgPropID=DBPROP_MAYWRITECOLUMN;
|
|
|
|
COMPARE(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
(struct _GUID*)&IID_IRowsetInfo), TRUE);
|
|
TESTC(CreateWithOneRowsetProps(rgPropID, VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
(struct _GUID*)&IID_IRowsetInfo));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(62)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Ask for a rowset mandatory/optional interface when table creation => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_62()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
IUnknown *pIRowset = NULL;
|
|
DBID *pTableID = NULL;
|
|
BOOL fMayWrite;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CList <WCHAR*, WCHAR*> ListNativeTemp;
|
|
CList <DBTYPE, DBTYPE> ListDataTypes;
|
|
CTable *pTable = NULL;
|
|
|
|
pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
// get the provider types list
|
|
pTable->CreateColInfo(ListNativeTemp, ListDataTypes, ALLTYPES);
|
|
// build the column description array
|
|
pTable->BuildColumnDescs(&rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc=pTable->CountColumnsOnTable());
|
|
pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
odtLog << "CreateTable and ask for a pointer to IRowset (mandatory)\n";
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
0, NULL), S_OK);
|
|
|
|
odtLog << "CreateTable and ask for a pointer to IRowsetChange (optional)\n";
|
|
CHECK(hr = CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetChange, 0, NULL, &pTableID, (IUnknown**)&pIRowset), S_OK);
|
|
|
|
// try to use the IRowsetChange interface to insert a row
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pTable->SetTableID(*pTableID);
|
|
pTable->MayWrite(&fMayWrite);
|
|
m_hr = Insert(0, (IRowsetChange*)pIRowset, 0, NULL, pTable);
|
|
if (DB_E_NOTSUPPORTED != m_hr)
|
|
{
|
|
TESTC_(m_hr, S_OK);
|
|
}
|
|
else
|
|
{
|
|
fTestRes = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
// checkings, etc
|
|
SAFE_RELEASE(pIRowset);
|
|
if (pTableID)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID);
|
|
}
|
|
delete pTable;
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
unsigned TCCreateTable::MyThreadProc(ULONG i)
|
|
{
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBID TableID;
|
|
DBID *pTableID = NULL;
|
|
HRESULT hr;
|
|
|
|
if (i>= nThreads)
|
|
return 0;
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, m_cColumnDesc);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_rgName[i];
|
|
Sleep(0); // switch the context
|
|
|
|
hr = m_pITableDefinition->CreateTable(NULL, m_rgName[i]? &TableID: NULL,
|
|
m_cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL,
|
|
m_rgName[i] ? NULL: &pTableID, NULL);
|
|
Sleep(0); // switch the context
|
|
|
|
m_rgResult[i] = hr;
|
|
if (!m_rgName[i] && pTableID && DBKIND_NAME == pTableID->eKind)
|
|
{
|
|
m_rgName[i] = pTableID->uName.pwszName;
|
|
SAFE_FREE(pTableID);
|
|
}
|
|
else
|
|
ReleaseDBID(pTableID);
|
|
ReleaseColumnDesc(rgColumnDesc, m_cColumnDesc);
|
|
return 1;
|
|
} //TCCreateTable::MyThreadProc
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(63)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc threads on different tables
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_63()
|
|
{
|
|
TBEGIN
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
ULONG i;
|
|
WCHAR number[3];
|
|
LPWSTR pwszBaseName = NULL;
|
|
DBID TableID;
|
|
|
|
odtLog << "All table names are generated by user\n";
|
|
m_pTable->MakeTableName(NULL);
|
|
pwszBaseName = m_pTable->GetTableName();
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
|
|
m_rgResult[i] = E_FAIL;
|
|
|
|
m_rgName[i] = (WCHAR*)PROVIDER_ALLOC((3+wcslen(pwszBaseName))*sizeof(WCHAR));
|
|
ASSERT(m_rgName[i]);
|
|
wcscpy(m_rgName[i], pwszBaseName);
|
|
swprintf(number, L"%02d", i);
|
|
wcscat(m_rgName[i], number);
|
|
}
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
if (CHECK(m_rgResult[i], S_OK))
|
|
{
|
|
TableID.uName.pwszName = m_rgName[i];
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
}
|
|
}
|
|
|
|
odtLog << "All table names are provider generated\n";
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
|
|
m_rgResult[i] = E_FAIL;
|
|
m_rgName[i] = NULL;
|
|
}
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
CHECK(m_rgResult[i], S_OK);
|
|
|
|
CLEANUP:
|
|
TableID.eKind = DBKIND_NAME;
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
TableID.uName.pwszName = m_rgName[i];
|
|
if (SUCCEEDED(m_rgResult[i]))
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
PROVIDER_FREE(m_rgName[i]);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(64)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc threads on the same table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_64()
|
|
{
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
BOOL fTestResult = TEST_FAIL;
|
|
ULONG i, nS_OK, nDB_E_DUPLICATETABLEID;
|
|
LPWSTR pwszBaseName = NULL;
|
|
DBID TableID;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
pwszBaseName = m_pTable->GetTableName();
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = E_FAIL;
|
|
m_rgName[i] = pwszBaseName;
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// creates a table, build rgColumnDesc by it
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=nS_OK=nDB_E_DUPLICATETABLEID=0; i<nThreads; i++)
|
|
{
|
|
if (m_rgResult[i] == S_OK)
|
|
nS_OK++;
|
|
else if (CHECK(m_rgResult[i], DB_E_DUPLICATETABLEID))
|
|
nDB_E_DUPLICATETABLEID++;
|
|
else
|
|
{
|
|
odtLog << "Thread " << i << ": unexpected result " << m_rgResult[i] << "\n";
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
TESTC(nS_OK == 1 && nDB_E_DUPLICATETABLEID == nThreads-1);
|
|
fTestResult = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = pwszBaseName;
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
return fTestResult;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(65)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc try all interfaces on rowset that can be returned
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_65()
|
|
{
|
|
TBEGIN
|
|
const ULONG nInterfaces = 19; // number of total interfaces
|
|
const ULONG nMandatoryInterfaces = 6; // the number of mandatory interfaces
|
|
const IID* rgRIIDInterfaces[nInterfaces] = {&IID_IUnknown, &IID_IAccessor, &IID_IColumnsInfo,
|
|
&IID_IConvertType, &IID_IRowset, &IID_IRowsetInfo, &IID_IChapteredRowset,
|
|
&IID_IColumnsRowset, &IID_IConnectionPointContainer, &IID_IDBAsynchStatus,
|
|
&IID_IRowsetChange, &IID_IRowsetFind, &IID_IRowsetIdentity, &IID_IRowsetLocate,
|
|
&IID_IRowsetResynch, &IID_IRowsetScroll, &IID_IRowsetUpdate, &IID_IRowsetView,
|
|
&IID_ISupportErrorInfo};
|
|
LPWSTR rgInterfaceNames[nInterfaces] = {L"IUnknown", L"IAccessor", L"IColumnsInfo",
|
|
L"IConvertType", L"IRowset", L"IRowsetInfo", L"IChapteredRowset",
|
|
L"IColumnsRowset", L"IConnectionPointContainer", L"IDBAsynchStatus",
|
|
L"IRowsetChange", L"IRowsetFind", L"IRowsetIdentity", L"IRowsetLocate",
|
|
L"IRowsetResynch", L"IRowsetScroll", L"IRowsetUpdate", L"IRowsetView",
|
|
L"ISupportErrorInfo"};
|
|
const DBPROPID rgInterfaceID[nInterfaces-1] = {DBPROP_IAccessor, DBPROP_IColumnsInfo,
|
|
DBPROP_IConvertType, DBPROP_IRowset, DBPROP_IRowsetInfo, DBPROP_IChapteredRowset,
|
|
DBPROP_IColumnsRowset, DBPROP_IConnectionPointContainer, DBPROP_IDBAsynchStatus,
|
|
DBPROP_IRowsetChange, DBPROP_IRowsetFind, DBPROP_IRowsetIdentity, DBPROP_IRowsetLocate,
|
|
DBPROP_IRowsetResynch, DBPROP_IRowsetScroll, DBPROP_IRowsetUpdate, DBPROP_IRowsetView,
|
|
DBPROP_ISupportErrorInfo};
|
|
// BOOL fTestRes = TEST_PASS;
|
|
ULONG i, j;
|
|
IUnknown *pRowset = NULL;
|
|
IUnknown *pIUnknown = NULL;
|
|
DBPROPSET rgPropertySets[2];
|
|
DBPROP rgProperties[nInterfaces-1];
|
|
DBPROP rgProp2[1];
|
|
DBID *pTableID = NULL;
|
|
HRESULT hr;
|
|
HRESULT hRes = S_OK;
|
|
HRESULT hExpectedRes = S_OK;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
BOOL fRetrieve = true;
|
|
BOOL fPropSupported;
|
|
|
|
FILL_PROP_SET(rgPropertySets[0], NUMELEM(rgProperties), rgProperties, DBPROPSET_ROWSET);
|
|
for (i=0; i<nInterfaces-1; i++)
|
|
{
|
|
FILL_PROP(rgProperties[i], rgInterfaceID[i], VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL);
|
|
if (!SupportedProperty(rgInterfaceID[i], DBPROPSET_ROWSET))
|
|
hRes = DB_S_ERRORSOCCURRED;
|
|
}
|
|
FILL_PROP_SET(rgPropertySets[1], NUMELEM(rgProp2), rgProp2, DBPROPSET_ROWSET);
|
|
FILL_PROP(rgProp2[0], DBPROP_ISequentialStream, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL);
|
|
if (!SupportedProperty(DBPROP_ISequentialStream, DBPROPSET_ROWSET))
|
|
hRes = DB_S_ERRORSOCCURRED;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
for (i=0; i<nInterfaces; i++)
|
|
{
|
|
odtLog << "\t" << rgInterfaceNames[i] << ((i<nMandatoryInterfaces)? "(mandatory)\n" : "\n");
|
|
PRVTRACE(L"TCCreateTable::Variation_65(): iteration %d (%s)\n",
|
|
i, ((i>0) ? rgInterfaceNames[i] : L"IUnknown"));
|
|
fPropSupported = (i>0)? SupportedProperty(rgInterfaceID[i-1], DBPROPSET_ROWSET): TRUE;
|
|
hExpectedRes = ((i>0) && !fPropSupported)? E_NOINTERFACE: hRes;
|
|
|
|
// This interface is only supported if user sets DBPROP_ROWSET_ASYNCH in the
|
|
// rowset properties otherwise its unsupported.
|
|
if (i>0 && rgInterfaceID[i-1] == DBPROP_IDBAsynchStatus)
|
|
{
|
|
fPropSupported = FALSE;
|
|
hExpectedRes = E_NOINTERFACE;
|
|
}
|
|
|
|
// if the interface is mandatory, it has to be supported
|
|
// note that there is not a DBPROP_IUnknown, so the condition is i>nMandatoryInterfaces
|
|
COMPARE(i==0 || fPropSupported || i>=nMandatoryInterfaces, TRUE);
|
|
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc,
|
|
*rgRIIDInterfaces[i], 0, NULL,
|
|
FALSE), fPropSupported? S_OK: E_NOINTERFACE);
|
|
|
|
pRowset = NULL;
|
|
CHECK(hr = CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
*rgRIIDInterfaces[i], NUMELEM(rgPropertySets), rgPropertySets,
|
|
&pTableID, &pRowset), hExpectedRes);
|
|
|
|
if (S_OK != hr && DB_S_ERRORSOCCURRED != hr)
|
|
{
|
|
if (i<nMandatoryInterfaces)
|
|
{
|
|
odtLog << "could not get the mandatory interface " << rgInterfaceNames[i] << "\n";
|
|
COMPARE(TRUE, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// try to get all the other interfaces
|
|
if (pRowset)
|
|
{
|
|
fRetrieve = CHECK(pRowset->QueryInterface(IID_IUnknown,
|
|
(void**)&pIUnknown), S_OK) ? fRetrieve: FALSE;
|
|
SAFE_RELEASE(pIUnknown);
|
|
|
|
// all the other interfaces considered
|
|
for (j=1; j<nInterfaces; j++)
|
|
{
|
|
odtLog << "\tTesting: " << rgInterfaceNames[j] << "\n";
|
|
|
|
if ( (j<nMandatoryInterfaces)
|
|
&& ( !COMPARE(rgProperties[j-1].dwStatus, DBPROPSTATUS_OK)
|
|
|| !CHECK(pRowset->QueryInterface(*rgRIIDInterfaces[j], (void**)&pIUnknown), S_OK)))
|
|
{
|
|
odtLog << "Could not retrieve mandatory interface " << rgInterfaceNames[j] << "\n";
|
|
continue;
|
|
}
|
|
SAFE_RELEASE(pIUnknown);
|
|
fRetrieve = TRUE;
|
|
// the interface should be retrievable if and only if the propstatus is ok
|
|
if (DBPROPSTATUS_OK == rgProperties[j-1].dwStatus)
|
|
{
|
|
fRetrieve = CHECK(pRowset->QueryInterface(*rgRIIDInterfaces[j],
|
|
(void**)&pIUnknown), S_OK) ? fRetrieve: FALSE;
|
|
SAFE_RELEASE(pIUnknown);
|
|
}
|
|
else
|
|
{
|
|
fRetrieve = CHECK(pRowset->QueryInterface(*rgRIIDInterfaces[j],
|
|
(void**)&pIUnknown), E_NOINTERFACE) ? fRetrieve: FALSE;
|
|
}
|
|
// check on prop status
|
|
if (SupportedProperty(rgInterfaceID[j-1], DBPROPSET_ROWSET))
|
|
{
|
|
if (SettableProperty(rgInterfaceID[j-1], DBPROPSET_ROWSET))
|
|
fRetrieve = ((DBPROPSTATUS_NOTSET != rgProperties[j-1].dwStatus
|
|
&& !COMPARE(rgProperties[j-1].dwStatus, DBPROPSTATUS_OK))) ? FALSE: fRetrieve;
|
|
else
|
|
fRetrieve = (DBPROPSTATUS_OK != rgProperties[j-1].dwStatus
|
|
&& !COMPARE(rgProperties[j-1].dwStatus, DBPROPSTATUS_NOTSETTABLE)) ? FALSE: fRetrieve;
|
|
}
|
|
else
|
|
{
|
|
fRetrieve = (!COMPARE(rgProperties[j-1].dwStatus, DBPROPSTATUS_NOTSUPPORTED))? FALSE: fRetrieve;
|
|
}
|
|
if (!fRetrieve)
|
|
{
|
|
odtLog << "ERROR: retrieving interface " << rgInterfaceNames[j] << "\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (pRowset)
|
|
SAFE_RELEASE(pRowset);
|
|
if (pTableID)
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID);
|
|
}
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(66)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc create with a table property => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_66()
|
|
// just try the creation of a table with the specified property
|
|
// there is not any method to retrieve the property of the table
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSets[1];
|
|
DBPROP rgProp[1];
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID TableID;
|
|
BOOL fSupported;
|
|
BOOL fSettable;
|
|
BOOL fValidate;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
|
|
fSupported = SupportedProperty(DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE);
|
|
fSettable = SettableProperty(DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE);
|
|
fValidate = fSettable || !fSupported;
|
|
|
|
hr = fSettable? S_OK : DB_E_ERRORSOCCURRED;
|
|
|
|
odtLog << "Property is REQUIRED\n";
|
|
// temp table, TableID generated by provider
|
|
odtLog << "\tProvider generated TableID\n";
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProp), rgProp, DBPROPSET_TABLE);
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, NUMELEM(rgPropSets), rgPropSets);
|
|
if (fValidate && fSettable || S_OK == hr)
|
|
{
|
|
CHECK(hr, S_OK);
|
|
COMPARE(rgProp[0].dwStatus, DBPROPSTATUS_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
if (fSupported)
|
|
{ COMPARE(DBPROPSTATUS_NOTSETTABLE == rgProp[0].dwStatus, TRUE);}
|
|
else
|
|
{ COMPARE(DBPROPSTATUS_NOTSUPPORTED == rgProp[0].dwStatus, TRUE);}
|
|
}
|
|
|
|
// perm table, TableID generated by provider
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_FALSE, DBPROPOPTIONS_REQUIRED);
|
|
hr = (S_OK!=hr)? DB_E_ERRORSOCCURRED : S_OK;
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), hr);
|
|
|
|
// temp table, consumer generated TableID
|
|
odtLog << "\tConsumer generated TableID\n";
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = wcsDuplicate(m_pTable->GetTableName());
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProp), rgProp, DBPROPSET_TABLE);
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
hr = CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, NUMELEM(rgPropSets), rgPropSets);
|
|
|
|
// perm table, consumer generated TableID
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_FALSE, DBPROPOPTIONS_REQUIRED);
|
|
hr = (S_OK!=hr)? DB_E_ERRORSOCCURRED : S_OK;
|
|
CHECK(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), hr);
|
|
|
|
hr = fSettable? S_OK : DB_S_ERRORSOCCURRED;
|
|
|
|
odtLog << "Property is OPTIONAL\n";
|
|
// temp table, TableID generated by provider
|
|
odtLog << "\tProvider generated TableID\n";
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProp), rgProp, DBPROPSET_TABLE);
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL);
|
|
TEST2C_(hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), S_OK, DB_S_ERRORSOCCURRED);
|
|
|
|
// perm table, TableID generated by provider
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_FALSE, DBPROPOPTIONS_OPTIONAL);
|
|
hr = (S_OK!=hr)? DB_S_ERRORSOCCURRED : S_OK;
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), hr);
|
|
|
|
// temp table, consumer generated TableID
|
|
odtLog << "\tConsumer generated TableID\n";
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = wcsDuplicate(m_pTable->GetTableName());
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProp), rgProp, DBPROPSET_TABLE);
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL);
|
|
TEST2C_(hr = CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), S_OK, DB_S_ERRORSOCCURRED);
|
|
|
|
// perm table, consumer generated TableID
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_FALSE, DBPROPOPTIONS_OPTIONAL);
|
|
hr = (S_OK!=hr)? DB_S_ERRORSOCCURRED : S_OK;
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), hr);
|
|
|
|
CLEANUP:
|
|
// checkings, etc
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(67)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc create a table and update a row, using the rowset interface got => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_67()
|
|
{
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
IRowset *pIRowset = NULL;
|
|
IAccessor *pIAccessor = NULL;
|
|
BOOL fTestRes = TEST_FAIL;
|
|
ULONG i;
|
|
const ULONG nInsertRows = 10;
|
|
BOOL fMayWrite;
|
|
const ULONG nRows = 3;
|
|
DBPROPSET rgPropSets[1];
|
|
const ULONG nProps = 3;
|
|
DBPROP rgProperties[nProps];
|
|
HROW *rghRow = NULL;
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HACCESSOR hAccessor = NULL;
|
|
BYTE *pData = NULL;
|
|
DBCOUNTITEM cBindings = 0;
|
|
DBBINDING *rgBindings = NULL;
|
|
const LONG cColsToBind = 1;
|
|
LONG_PTR rgColsToBind[cColsToBind];
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CList <WCHAR*, WCHAR*> ListNativeTemp;
|
|
CList <DBTYPE, DBTYPE> ListDataTypes;
|
|
CTable *pTable = NULL;
|
|
|
|
pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
// get the provider types list
|
|
pTable->CreateColInfo(ListNativeTemp, ListDataTypes, ALLTYPES);
|
|
// build the column description array
|
|
pTable->BuildColumnDescs(&rgColumnDesc);
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc=pTable->CountColumnsOnTable());
|
|
pTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProperties), rgProperties, DBPROPSET_ROWSET);
|
|
FILL_PROP(rgProperties[0], DBPROP_IRowsetChange, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
FILL_PROP(rgProperties[1], DBPROP_OWNINSERT, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
FILL_PROP(rgProperties[2], DBPROP_OWNUPDATEDELETE, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL);
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc, IID_IRowsetChange, 1, rgPropSets,
|
|
&pTableID, (IUnknown**)&pIRowsetChange), S_OK);
|
|
|
|
pTable->SetTableID(*pTableID);
|
|
pTable->MayWrite(&fMayWrite);
|
|
for (i=0; i<nInsertRows; i++)
|
|
{
|
|
m_hr = Insert(0, pIRowsetChange, 0, NULL, pTable);
|
|
if (DB_E_NOTSUPPORTED != m_hr)
|
|
{
|
|
TESTC_(m_hr, S_OK);
|
|
}
|
|
else
|
|
{
|
|
fTestRes = TEST_SKIPPED;
|
|
goto CLEANUP;
|
|
}
|
|
|
|
}
|
|
|
|
// get a pointer to IRoewset interface
|
|
if (!VerifyInterface(pIRowsetChange, IID_IRowset, ROWSET_INTERFACE, (IUnknown**)&pIRowset))
|
|
{
|
|
odtLog << "could not get IRowsetChange\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
if (!VerifyInterface(pIRowset, IID_IAccessor, ROWSET_INTERFACE, (IUnknown**)&pIAccessor))
|
|
{
|
|
odtLog << "could not get IAccessor\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
m_hr = pIRowset->RestartPosition(NULL);
|
|
|
|
if (!CHECK(m_hr = pIRowset->GetNextRows(0, 0, // hChapter & lRowsOffset
|
|
nRows, // number of rows to be retrieved
|
|
&cRowsObtained, //number of rows actually get
|
|
&rghRow // array of handlers to rows
|
|
), S_OK) || nRows != cRowsObtained)
|
|
{
|
|
odtLog << "insuccess on IRowset::GetNextRows\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
rgColsToBind[0] = 1;
|
|
if (!CHECK(m_hr = GetAccessorAndBindings(pIRowset, // pIUnknRowsetObject
|
|
DBACCESSOR_ROWDATA, // accessor flags
|
|
&hAccessor, &rgBindings, &cBindings, NULL, // accessor handler, array and number of bindings created
|
|
DBPART_VALUE |DBPART_STATUS |DBPART_LENGTH, // types of bindings to do
|
|
USE_COLS_TO_BIND_ARRAY, // eColsByRef specifies that cols to be bind
|
|
//are gien as an array
|
|
FORWARD, // eBindingOrder
|
|
NO_COLS_BY_REF, // eColsByRef
|
|
NULL, NULL,
|
|
NULL, DBTYPE_EMPTY, // ppStringsBufferOut & dwModifier
|
|
cColsToBind, rgColsToBind), S_OK))
|
|
{
|
|
odtLog << "problems getting accessor and bindings\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// Fill buffer with appropriate data for insert of this row number
|
|
TESTC_(m_hr = FillInputBindings(
|
|
pTable,
|
|
DBACCESSOR_ROWDATA,
|
|
cBindings,
|
|
rgBindings,
|
|
&pData,
|
|
37,
|
|
0,
|
|
NULL),S_OK);
|
|
|
|
if (!CHECK(m_hr = pIRowsetChange->SetData(rghRow[0], hAccessor, pData), S_OK))
|
|
{
|
|
odtLog << "could not update the row\n";
|
|
goto CLEANUP;
|
|
}
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
if (pIAccessor && hAccessor)
|
|
{
|
|
CHECK(m_hr = pIAccessor->ReleaseAccessor(hAccessor, NULL), S_OK);
|
|
}
|
|
SAFE_RELEASE(pIAccessor);
|
|
if (pIRowset)
|
|
CHECK(m_hr = pIRowset->ReleaseRows(cRowsObtained, rghRow, NULL, NULL, NULL), S_OK);
|
|
PROVIDER_FREE(rghRow);
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
SAFE_RELEASE(pIRowset);
|
|
if (pTableID)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID);
|
|
}
|
|
delete pTable;
|
|
FreeAccessorBindings(cBindings, rgBindings);
|
|
PROVIDER_FREE(pData);
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(68)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Fully Qualified Table Name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_68()
|
|
{
|
|
BOOL fTestRes = TEST_FAIL;
|
|
DBID TableID;
|
|
WCHAR *pwszQualTableName = NULL;
|
|
WCHAR *pwszCatalogName = NULL;
|
|
WCHAR *pwszSchemaName = NULL;
|
|
WCHAR *pwszTableName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CTable *pTable = NULL;
|
|
|
|
// create a regular table
|
|
pTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
TESTC(NULL != pTable);
|
|
TESTC_(pTable->CreateTable(0, 0), S_OK);
|
|
pwszTableName = pTable->GetTableName();
|
|
TableID.eKind = DBKIND_NAME;
|
|
|
|
TESTC(GetCatalogSchemaNames(pwszTableName, &pwszCatalogName, &pwszSchemaName, pTable));
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(pTable->GetQualifiedName(pwszCatalogName, pwszSchemaName, pwszTableName, &pwszQualTableName),S_OK);
|
|
TableID.uName.pwszName = pwszQualTableName;
|
|
|
|
// get rid of the previous table; keep info about "the empty shell"
|
|
m_pITableDefinition->DropTable(&pTable->GetTableID());
|
|
|
|
// create the table with the qualified name
|
|
pTable->BuildColumnDescs(&rgColumnDesc);
|
|
pTable->SetColumnDesc(rgColumnDesc, cColumnDesc=pTable->CountColumnsOnTable());
|
|
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
SAFE_FREE(pwszQualTableName);
|
|
pTable->DropTable();
|
|
delete pTable;
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(69)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Quoted table name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_69()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
m_pTable->MakeTableName(NULL);
|
|
m_pTable->GetQuotedName(m_pTable->GetTableName(), &TableID.uName.pwszName);
|
|
TESTC_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(&TableID, FALSE);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(70)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Aggregation, non IID_IUnknown
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_70()
|
|
{
|
|
TBEGIN
|
|
DBID *pTableID = NULL;
|
|
CAggregate Aggregate(m_pIOpenRowset);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITableDefinition, &Aggregate, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetChange, 0, NULL, &pTableID, (IUnknown**)&Aggregate.m_pIUnkInner),
|
|
DB_E_NOAGGREGATION);
|
|
|
|
// Verrify Aggregation for this rowset...
|
|
TESTC(NULL == Aggregate.m_pIUnkInner);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
Aggregate.ReleaseInner();
|
|
// checkings, etc
|
|
DropTableAndCheck(pTableID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(71)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Aggregation -> IRowsetInfo::GetReferencedRowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_71()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBID *pTableID = NULL;
|
|
CAggregate Aggregate(m_pIOpenRowset);
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
IUnknown *pIAggregate = NULL;
|
|
IUnknown *pIUnkOuter = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
ULONG cPropSet = 0;
|
|
DBPROPSET *prgPropSet = NULL;
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// create a table and open a bookmark rowset on it
|
|
if (SettableProperty(DBPROP_BOOKMARKS, DBPROPSET_ROWSET))
|
|
{
|
|
FILL_PROP_SET(rgPropSet[0], 1, rgProp, DBPROPSET_ROWSET);
|
|
FILL_PROP(rgProp[0], DBPROP_BOOKMARKS, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
prgPropSet = rgPropSet;
|
|
cPropSet = 1;
|
|
}
|
|
TEST2C_(hr = CreateAndCheckTable(m_pITableDefinition, &Aggregate, NULL, cColumnDesc, rgColumnDesc, IID_IUnknown, cPropSet, prgPropSet,
|
|
&pTableID, (IUnknown**)&Aggregate.m_pIUnkInner), S_OK, DB_E_NOAGGREGATION);
|
|
TEST_PROVIDER(S_OK == hr);
|
|
|
|
//Verify Aggregation for this rowset...
|
|
TESTC(Aggregate.VerifyAggregationQI(hr, IID_IRowsetInfo, (IUnknown**)&pIRowsetInfo));
|
|
|
|
//Verify we are hooked up...
|
|
//This call we are using the Rowset and asking for IID_IAggregate,
|
|
//which is the outer object and should succeed!!! Kind of cool huh!
|
|
hr = pIRowsetInfo->GetReferencedRowset(0, IID_IAggregate, (IUnknown**)&pIAggregate);
|
|
TESTC(hr==S_OK || hr==DB_E_BADORDINAL ||hr==DB_E_NOTAREFERENCECOLUMN);
|
|
if(hr==DB_E_NOTAREFERENCECOLUMN || hr==DB_E_BADORDINAL)
|
|
TESTC(!GetProperty(DBPROP_BOOKMARKS, DBPROPSET_ROWSET, Aggregate.m_pIUnkInner, VARIANT_TRUE));
|
|
TESTC_PROVIDER(hr==S_OK);
|
|
|
|
//Now make sure the Rowset QI for IUnknown give me the outer
|
|
TESTC_(hr = pIRowsetInfo->GetReferencedRowset(0, IID_IUnknown, (IUnknown**)&pIUnkOuter),S_OK);
|
|
TESTC(VerifyEqualInterface(pIAggregate, pIUnkOuter));
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIAggregate);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
SAFE_RELEASE(pIUnkOuter);
|
|
Aggregate.ReleaseInner();
|
|
// checkings, etc
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(72)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Agg session -> IRowsetInfo::GetSpecification
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_72()
|
|
{
|
|
CAggregate Aggregate(g_pIDBCreateSession);
|
|
ULONG fTestRes = TEST_FAIL;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
ITableDefinition *pITableDefinition = NULL;
|
|
IUnknown *pIAggregate = NULL;
|
|
ULONG ulRefCountBefore;
|
|
ULONG ulRefCountAfter;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
//Aggregation
|
|
HRESULT hr = CreateNewSession(g_pIDBInitialize, IID_IUnknown, (IUnknown**)&Aggregate.m_pIUnkInner, &Aggregate);
|
|
|
|
TEST_PROVIDER(S_OK == hr);
|
|
|
|
//Verify Aggregation for this session...
|
|
TESTC(Aggregate.VerifyAggregationQI(hr, IID_ITableDefinition, (IUnknown**)&pITableDefinition));
|
|
|
|
//Now Create the Rowset
|
|
ulRefCountBefore = Aggregate.GetRefCount();
|
|
// create a table and open a bookmark rowset on it
|
|
TESTC_(CreateAndCheckTable(pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetInfo, 0, NULL, &pTableID, (IUnknown**)&pIRowsetInfo), S_OK);
|
|
ulRefCountAfter = Aggregate.GetRefCount();
|
|
|
|
//GetSpecification
|
|
TEST2C_(hr = pIRowsetInfo->GetSpecification(IID_IAggregate, (IUnknown**)&pIAggregate),S_OK,S_FALSE);
|
|
|
|
if(hr==S_OK)
|
|
{
|
|
TESTC(VerifyEqualInterface(pIAggregate, pITableDefinition));
|
|
|
|
//Verify the child correctly addref'd the parent outer.
|
|
//The is an absolute requirement that the child keep the parent outer alive.
|
|
//If it doesn't addref the outer, the outer can be released externally since
|
|
//its not being used anymore due to the fact the outer controls the refcount
|
|
//of the inner. Many providers incorrectly addref the inner, which does nothing
|
|
//but guareentee the inner survives, but the inner will delegate to the outer
|
|
//and crash since it no longer exists...
|
|
TCOMPARE_(ulRefCountAfter > ulRefCountBefore);
|
|
}
|
|
else
|
|
{
|
|
TWARNING(L"IRowsetInfo::GetSpecification unable to retrieve Parent object!");
|
|
}
|
|
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIAggregate);
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
Aggregate.ReleaseInner();
|
|
// checkings, etc
|
|
if (pITableDefinition)
|
|
CHECK(DropTableAndCheck(pTableID, pITableDefinition), S_OK);
|
|
SAFE_RELEASE(pITableDefinition);
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(73)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table -> Agg ColumnRowset, ask for non IID_IUnknown
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_73()
|
|
{
|
|
TBEGIN
|
|
DBID *pTableID = NULL;
|
|
CAggregate Aggregate(m_pIOpenRowset);
|
|
IRowset *pIRowset = NULL;
|
|
IColumnsRowset *pIColumnsRowset = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPSET *rgPropSet = NULL;
|
|
ULONG cPropSet = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
SetSettableProperty(DBPROP_IColumnsRowset, DBPROPSET_ROWSET, &cPropSet, &rgPropSet);
|
|
TESTC_(CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowset, cPropSet, rgPropSet, &pTableID, (IUnknown**)&pIRowset), S_OK);
|
|
|
|
//Obtain the ColumnsRowset interface [OPTIONAL] interface
|
|
TESTC_PROVIDER(VerifyInterface(pIRowset, IID_IColumnsRowset, ROWSET_INTERFACE, (IUnknown**)&pIColumnsRowset));
|
|
|
|
//Try to obtain anything but IID_IUnknown.
|
|
//This should fail, this is a requirement for COM Aggregation...
|
|
TESTC_(pIColumnsRowset->GetColumnsRowset(&Aggregate, 0, NULL, IID_IRowset, 0, NULL,
|
|
(IUnknown**)&Aggregate.m_pIUnkInner),DB_E_NOAGGREGATION);
|
|
|
|
//Inner object cannot RefCount the outer object - COM rule for CircularRef
|
|
TESTC(Aggregate.GetRefCount() == 1);
|
|
TESTC(Aggregate.m_pIUnkInner == NULL);
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIColumnsRowset);
|
|
SAFE_RELEASE(pIRowset);
|
|
Aggregate.ReleaseInner();
|
|
DropTableAndCheck(pTableID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(74)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table -> Agg ColumnRowset, ask for IID_IUnknown
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_74()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBID *pTableID = NULL;
|
|
CAggregate Aggregate(m_pIOpenRowset);
|
|
IRowset *pIRowset = NULL;
|
|
IColumnsRowset *pIColumnsRowset = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPSET *rgPropSet = NULL;
|
|
ULONG cPropSet = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
SetSettableProperty(DBPROP_IColumnsRowset, DBPROPSET_ROWSET, &cPropSet, &rgPropSet);
|
|
TEST2C_(hr = CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowset, cPropSet, rgPropSet, &pTableID, (IUnknown**)&pIRowset), S_OK, DB_E_ERRORSOCCURRED);
|
|
|
|
if (DB_E_ERRORSOCCURRED == hr)
|
|
TESTC(!GetProperty(DBPROP_IColumnsRowset, DBPROPSET_ROWSET, pIRowset, VARIANT_TRUE));
|
|
TESTC_PROVIDER(S_OK == hr);
|
|
|
|
//Obtain the ColumnsRowset interface [OPTIONAL] interface
|
|
TESTC_PROVIDER(VerifyInterface(pIRowset, IID_IColumnsRowset, ROWSET_INTERFACE, (IUnknown**)&pIColumnsRowset));
|
|
|
|
//Try to obtain IID_IUnknown.
|
|
TEST2C_(hr = pIColumnsRowset->GetColumnsRowset(&Aggregate, 0, NULL, IID_IUnknown, 0, NULL,
|
|
(IUnknown**)&Aggregate.m_pIUnkInner), S_OK, DB_E_NOAGGREGATION);
|
|
TESTC_PROVIDER(S_OK == hr);
|
|
//Verify Aggregation for this session...
|
|
TESTC(Aggregate.VerifyAggregationQI(hr, IID_IRowset));
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIColumnsRowset);
|
|
SAFE_RELEASE(pIRowset);
|
|
Aggregate.ReleaseInner();
|
|
// checkings, etc
|
|
DropTableAndCheck(pTableID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(75)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table -> Agg ColumnRowset -> IRowsetInfo::GetSpecification
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_75()
|
|
{
|
|
TBEGIN
|
|
CAggregate Aggregate(m_pIOpenRowset);
|
|
ULONG fTestRes = TEST_FAIL;
|
|
IRowset *pIRowset = NULL;
|
|
IColumnsRowset *pIColumnsRowset = NULL;
|
|
IUnknown *pIAggregate = NULL;
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
ULONG ulRefCountBefore;
|
|
ULONG ulRefCountAfter;
|
|
HRESULT hr = S_OK;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPSET *rgPropSet = NULL;
|
|
ULONG cPropSet = 0;
|
|
DBID *pTableID = NULL;
|
|
BOOL fCreatedTable = FALSE;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
SetSettableProperty(DBPROP_IColumnsRowset, DBPROPSET_ROWSET, &cPropSet, &rgPropSet);
|
|
TEST3C_(hr = CreateAndCheckTable(m_pITableDefinition, &Aggregate, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IUnknown, cPropSet, rgPropSet, &pTableID, (IUnknown**)&Aggregate.m_pIUnkInner),
|
|
S_OK, DB_E_ERRORSOCCURRED, DB_E_NOAGGREGATION);
|
|
|
|
if (DB_E_ERRORSOCCURRED == hr)
|
|
TESTC(!GetProperty(DBPROP_IColumnsRowset, DBPROPSET_ROWSET, pIRowset, VARIANT_TRUE));
|
|
|
|
TESTC_PROVIDER(S_OK == hr);
|
|
fCreatedTable = TRUE;
|
|
|
|
//Verify Aggregation
|
|
TESTC(Aggregate.VerifyAggregationQI(hr, IID_IRowset, (IUnknown**)&pIRowset));
|
|
|
|
//Obtain the ColumnsRowset interface [OPTIONAL] interface
|
|
TESTC_PROVIDER(VerifyInterface(pIRowset, IID_IColumnsRowset, ROWSET_INTERFACE, (IUnknown**)&pIColumnsRowset));
|
|
|
|
//IColumnsRowset::GetRowset
|
|
ulRefCountBefore = Aggregate.GetRefCount();
|
|
TESTC_(hr = pIColumnsRowset->GetColumnsRowset(NULL, 0, NULL, IID_IRowsetInfo, 0, NULL, (IUnknown**)&pIRowsetInfo),S_OK);
|
|
ulRefCountAfter = Aggregate.GetRefCount();
|
|
|
|
//GetSpecification
|
|
TEST2C_(hr = pIRowsetInfo->GetSpecification(IID_IAggregate, (IUnknown**)&pIAggregate),S_OK,S_FALSE);
|
|
|
|
if(hr==S_OK)
|
|
{
|
|
TESTC(VerifyEqualInterface(pIAggregate, pIRowset));
|
|
|
|
//Verify the child correctly addref'd the parent outer.
|
|
//The is an absolute requirement that the child keep the parent outer alive.
|
|
//If it doesn't addref the outer, the outer can be released externally since
|
|
//its not being used anymore due to the fact the outer controls the refcount
|
|
//of the inner. Many providers incorrectly addref the inner, which does nothing
|
|
//but guareentee the inner survives, but the inner will delegate to the outer
|
|
//and crash since it no longer exists...
|
|
TCOMPARE_(ulRefCountAfter > ulRefCountBefore);
|
|
}
|
|
else
|
|
{
|
|
TWARNING(L"IRowsetInfo::GetSpecification unable to retrieve Parent object!");
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
SAFE_RELEASE(pIAggregate);
|
|
SAFE_RELEASE(pIColumnsRowset);
|
|
SAFE_RELEASE(pIRowset);
|
|
Aggregate.ReleaseInner();
|
|
// checkings, etc
|
|
CHECK(DropTableAndCheck(pTableID), fCreatedTable? S_OK : E_INVALIDARG);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(76)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc colid is ignored in a non column specific rowset property
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_76()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
DBPROPID dwPropID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
HRESULT hr;
|
|
DBPROPSTATUS dwStatus;
|
|
|
|
// make sure there is a non column specific rowset property that is settable
|
|
TESTC_PROVIDER(GetNonColSpecProp(DBPROPSET_ROWSET, &dwPropID));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
|
|
FILL_PROP_SET(rgPropSet[0], 1, rgProp, DBPROPSET_ROWSET)
|
|
FILL_PROP(rgProp[0], dwPropID, DBTYPE_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL)
|
|
|
|
// get the result with DB_NULLID
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropSet);
|
|
|
|
dwStatus = rgProp[0].dwStatus;
|
|
if (S_OK != hr)
|
|
{
|
|
TESTC_(hr, DB_S_ERRORSOCCURRED);
|
|
TESTC(DBPROPSTATUS_NOTSUPPORTED == dwStatus);
|
|
}
|
|
else
|
|
{
|
|
TESTC(DBPROPSTATUS_OK == dwStatus);
|
|
}
|
|
|
|
// set colID to a value different from DB_NULLID
|
|
rgProp[0].colid.eKind = DBKIND_NAME;
|
|
rgProp[0].colid.uName.pwszName = L"someColumn";
|
|
|
|
// check colid is ignored for the rowset property
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropSet), hr);
|
|
TESTC(dwStatus == rgProp[0].dwStatus);
|
|
|
|
// check colid is ignored for the column property
|
|
rgProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
1, rgPropSet), S_OK == hr? S_OK: DB_E_ERRORSOCCURRED);
|
|
TESTC(dwStatus == rgProp[0].dwStatus);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(77)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc colid is DB_NULLID in a column specific rowset property => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_77()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
DBPROPID dwPropID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
HRESULT hr;
|
|
|
|
// make sure there is a column specific rowset property that is settable
|
|
TESTC_PROVIDER(GetColSpecProp(DBPROPSET_ROWSET, &dwPropID));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
|
|
FILL_PROP_SET(rgPropSet[0], 1, rgProp, DBPROPSET_ROWSET)
|
|
FILL_PROP(rgProp[0], dwPropID, DBTYPE_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL)
|
|
|
|
// explicitly set colID to DB_NULLID
|
|
rgProp[0].colid = DB_NULLID;
|
|
|
|
// check colid is ignored for the rowset property
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropSet);
|
|
if (DB_S_ERRORSOCCURRED == hr)
|
|
{
|
|
TESTC(DBPROPSTATUS_NOTALLSETTABLE == rgProp[0].dwStatus);
|
|
}
|
|
else
|
|
{
|
|
TESTC_(hr, S_OK);
|
|
TESTC(DBPROPSTATUS_OK == rgProp[0].dwStatus);
|
|
}
|
|
|
|
// check colid is ignored for the column property
|
|
rgProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
|
|
// check colid is ignored for the rowset property
|
|
hr = CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropSet);
|
|
if (DB_E_ERRORSOCCURRED == hr)
|
|
{
|
|
TESTC(DBPROPSTATUS_NOTALLSETTABLE == rgProp[0].dwStatus);
|
|
}
|
|
else
|
|
{
|
|
TESTC_(hr, S_OK);
|
|
TESTC(DBPROPSTATUS_OK == rgProp[0].dwStatus);
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(78)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc valid, non DB_NULLID colid for a column specific rowset property
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_78()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
DBPROPID dwPropID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
memset(&rgProp[0].colid, 0, sizeof(DBID));
|
|
|
|
// make sure there is a column specific rowset property that is settable
|
|
TESTC_PROVIDER(GetColSpecProp(DBPROPSET_ROWSET, &dwPropID));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
|
|
FILL_PROP_SET(rgPropSet[0], 1, rgProp, DBPROPSET_ROWSET)
|
|
FILL_PROP(rgProp[0], dwPropID, DBTYPE_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL)
|
|
|
|
// explicitly set colID to DB_NULLID
|
|
DuplicateDBID(m_rgColumnDesc[0].dbcid, &rgProp[0].colid);
|
|
|
|
// check colid is ignored for the rowset property
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropSet), S_OK);
|
|
COMPARE(DBPROPSTATUS_OK == rgProp[0].dwStatus, TRUE);
|
|
|
|
// check colid is ignored for the column property
|
|
rgProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
|
|
// check colid is ignored for the rowset property
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropSet), S_OK);
|
|
COMPARE(DBPROPSTATUS_OK == rgProp[0].dwStatus, TRUE);
|
|
|
|
CLEANUP:
|
|
ReleaseDBID(&rgProp[0].colid, FALSE);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(79)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc invalid colid for a column specific rowset property
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_79()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSet[1];
|
|
DBPROP rgProp[1];
|
|
DBPROPID dwPropID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
// make sure there is a column specific rowset property that is settable
|
|
TESTC_PROVIDER(GetColSpecProp(DBPROPSET_ROWSET, &dwPropID));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
rgColumnDesc[0].cPropertySets = 0;
|
|
rgColumnDesc[0].rgPropertySets = NULL;
|
|
|
|
FILL_PROP_SET(rgPropSet[0], 1, rgProp, DBPROPSET_ROWSET)
|
|
FILL_PROP(rgProp[0], dwPropID, DBTYPE_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_OPTIONAL)
|
|
|
|
// set colID to a value different from DB_NULLID
|
|
rgProp[0].colid.eKind = DBKIND_NAME;
|
|
rgProp[0].colid.uName.pwszName = L"someColumn";
|
|
|
|
// check colid is ignored for the rowset property
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropSet), DB_S_ERRORSOCCURRED);
|
|
COMPARE(DBPROPSTATUS_BADCOLUMN == rgProp[0].dwStatus, TRUE);
|
|
|
|
// check colid is ignored for the column property
|
|
rgProp[0].dwOptions = DBPROPOPTIONS_REQUIRED;
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 1, rgPropSet), DB_E_ERRORSOCCURRED);
|
|
COMPARE(DBPROPSTATUS_BADCOLUMN == rgProp[0].dwStatus, TRUE);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(80)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table. Retrieve a rowset on it (IRowsetInfo). Check GetSpecification()
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_80()
|
|
{
|
|
IRowsetInfo *pIRowsetInfo = NULL;
|
|
IOpenRowset *pIOpenRowset = NULL;
|
|
BOOL fTestRes = TEST_FAIL;
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
HRESULT hr;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc, IID_IRowsetInfo,
|
|
0, NULL, &pTableID, (IUnknown**)&pIRowsetInfo), S_OK);
|
|
|
|
hr = pIRowsetInfo->GetSpecification(IID_IOpenRowset, (IUnknown**)&pIOpenRowset);
|
|
if (S_FALSE != hr)
|
|
{
|
|
TESTC_(hr, S_OK);
|
|
TESTC(VerifyEqualInterface(m_pITableDefinition, pIOpenRowset));
|
|
}
|
|
|
|
fTestRes = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetInfo);
|
|
SAFE_RELEASE(pIOpenRowset);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
if (pTableID)
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID);
|
|
return fTestRes;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(81)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DB_NULLID is ignored for non column-related table properties
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_81()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSets[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPID dwPropID;
|
|
|
|
// make sure there is a non column specific rowset property that is settable
|
|
TESTC_PROVIDER(GetNonColSpecProp(DBPROPSET_TABLE, &dwPropID));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProp), rgProp, DBPROPSET_TABLE);
|
|
FILL_PROP(rgProp[0], dwPropID, VT_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
// setting a colid != DB_NULLID for a table property should result in error
|
|
rgProp[0].colid.eKind = DBKIND_NAME;
|
|
rgProp[0].colid.uName.pwszName = L"AliBaba";
|
|
|
|
CHECK(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), S_OK);
|
|
|
|
// TableID generated by provider
|
|
FILL_PROP(rgProp[0], dwPropID, VT_BOOL, V_BOOL,
|
|
VARIANT_FALSE, DBPROPOPTIONS_REQUIRED);
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), S_OK);
|
|
|
|
CLEANUP:
|
|
// checkings, etc
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(82)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Column related table property set to bad colid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_82()
|
|
{
|
|
TBEGIN
|
|
DBPROPSET rgPropSets[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBPROPID dwPropID;
|
|
|
|
// make sure there is a non column specific rowset property that is settable
|
|
TESTC_PROVIDER(GetColSpecProp(DBPROPSET_TABLE, &dwPropID));
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProp), rgProp, DBPROPSET_TABLE);
|
|
FILL_PROP(rgProp[0], dwPropID, VT_BOOL, V_BOOL,
|
|
VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
// setting a colid != DB_NULLID for a table property should result in error
|
|
rgProp[0].colid.eKind = DBKIND_NAME;
|
|
rgProp[0].colid.uName.pwszName = L"AliBaba";
|
|
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), DB_S_ERRORSOCCURRED);
|
|
|
|
// TableID generated by provider
|
|
FILL_PROP(rgProp[0], dwPropID, VT_BOOL, V_BOOL,
|
|
VARIANT_FALSE, DBPROPOPTIONS_REQUIRED);
|
|
TESTC_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset,
|
|
NUMELEM(rgPropSets), rgPropSets), DB_E_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
// checkings, etc
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(83)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc How many DBTYPE_I4 columns?
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_83()
|
|
{
|
|
return TEST_PASS;
|
|
/*
|
|
TBEGIN
|
|
CTable *pCTable = new CTable(m_pThisTestModule->m_pIUnknown2,
|
|
(LPWSTR)gwszModuleName);
|
|
DBTYPE dbType = DBTYPE_I4;
|
|
BYTE precision = 0;
|
|
BYTE scale = 0;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
const ULONG MAX_VAL = 2048;
|
|
ULONG cColumnDesc = MAX_VAL / 2;
|
|
ULONG iCol;
|
|
ULONG offset = MAX_VAL / 4;
|
|
|
|
pCTable->SetBuildColumnDesc(FALSE);
|
|
for (;0 < offset;)
|
|
{
|
|
SAFE_ALLOC(rgColumnDesc, DBCOLUMNDESC, cColumnDesc);
|
|
memset(rgColumnDesc, 0, cColumnDesc*sizeof(DBCOLUMNDESC));
|
|
for (iCol = 0; iCol < cColumnDesc; iCol++)
|
|
{
|
|
// fill in a column
|
|
rgColumnDesc[iCol].wType = dbType;
|
|
rgColumnDesc[iCol].bPrecision = precision;
|
|
rgColumnDesc[iCol].bScale = scale;
|
|
rgColumnDesc[iCol].dbcid.eKind = DBKIND_NAME;
|
|
SAFE_ALLOC(rgColumnDesc[iCol].dbcid.uName.pwszName, WCHAR, 10);
|
|
swprintf(rgColumnDesc[iCol].dbcid.uName.pwszName, L"C%dCol", iCol);
|
|
}
|
|
|
|
pCTable->SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
hr = pCTable->CreateTable(100, 0);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pCTable->DropTable();
|
|
if (cColumnDesc < MAX_VAL)
|
|
cColumnDesc += offset;
|
|
else
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (cColumnDesc < offset)
|
|
break;
|
|
cColumnDesc -= offset;
|
|
}
|
|
offset /= 2;
|
|
}
|
|
odtLog << "Max no of columns : " << cColumnDesc << "\n";
|
|
|
|
CLEANUP:
|
|
pCTable->DropTable();
|
|
|
|
SAFE_DELETE(pCTable);
|
|
TRETURN
|
|
*/
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(84)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Open a rowset with CE, call IColumnRowset with an aggregated pIUnk
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_84()
|
|
{
|
|
TBEGIN
|
|
IRowsetFind *pIRowsetFind = NULL;
|
|
IColumnsRowset *pIColumnsRowset= NULL;
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
HRESULT hr;
|
|
CAggregate Aggregate(NULL);
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_IRowsetFind, DBPROPSET_ROWSET));
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
TEST2C_(hr = CreateAndCheckTable(m_pITableDefinition, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowsetFind, 0, NULL, &pTableID, (IUnknown**)&pIRowsetFind), S_OK, E_NOINTERFACE);
|
|
|
|
TESTC_PROVIDER(S_OK == hr);
|
|
|
|
TESTC_(pIRowsetFind->QueryInterface(IID_IColumnsRowset, (LPVOID*)&pIColumnsRowset), S_OK);
|
|
TESTC_(hr = pIColumnsRowset->GetColumnsRowset(&Aggregate, 0, NULL, IID_IUnknown,
|
|
0, NULL, (IUnknown**)&Aggregate.m_pIUnkInner), S_OK);
|
|
|
|
// Verify Aggregation for this rowset...
|
|
TESTC(Aggregate.VerifyAggregationQI(hr, IID_IRowset));
|
|
|
|
CLEANUP:
|
|
Aggregate.ReleaseInner();
|
|
SAFE_RELEASE(pIRowsetFind);
|
|
SAFE_RELEASE(pIColumnsRowset);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
if (pTableID)
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(85)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Different DBKINDs for pTableID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_85()
|
|
{
|
|
TBEGIN
|
|
LPWSTR pwszColumnName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID TableID;
|
|
HRESULT hr;
|
|
// DBKIND_GUID_NAME
|
|
// DBKIND_GUID_PROPID
|
|
// DBKIND_NAME
|
|
// DBKIND_PGUID_NAME
|
|
// DBKIND_PGUID_PROPID
|
|
// DBKIND_PROPID
|
|
// DBKIND_GUID
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
TEST2C_(hr = CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IUnknown,
|
|
0, NULL, TRUE), S_OK, DB_E_BADTABLEID);
|
|
|
|
TableID.eKind = DBKIND_GUID_NAME;
|
|
TableID.uGuid.guid = guidModule;
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
TEST2C_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL, TRUE), S_OK, DB_E_BADTABLEID);
|
|
|
|
TableID.eKind = DBKIND_PGUID_NAME;
|
|
TableID.uGuid.pguid = &guidModule;
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
TEST2C_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL, TRUE), S_OK, DB_E_BADTABLEID);
|
|
|
|
TableID.eKind = DBKIND_GUID;
|
|
TableID.uGuid.guid = guidModule;
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
TEST2C_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL, TRUE), S_OK, DB_E_BADTABLEID);
|
|
|
|
TableID.eKind = DBKIND_GUID_PROPID;
|
|
TableID.uGuid.guid = guidModule;
|
|
TableID.uName.ulPropid = 0xffL;
|
|
TEST2C_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL, TRUE), S_OK, DB_E_BADTABLEID);
|
|
|
|
TableID.eKind = DBKIND_PGUID_PROPID;
|
|
TableID.uGuid.pguid = &guidModule;
|
|
TableID.uName.ulPropid = 0xffL;
|
|
TEST2C_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL, TRUE), S_OK, DB_E_BADTABLEID);
|
|
|
|
TableID.eKind = DBKIND_PROPID;
|
|
TableID.uGuid.pguid = &guidModule;
|
|
TableID.uName.ulPropid = 0xffL;
|
|
TEST2C_(CCNDropTable(&TableID, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL, TRUE), S_OK, DB_E_BADTABLEID);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(86)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Different DBKINDs for column IDs
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTable::Variation_86()
|
|
{
|
|
TBEGIN
|
|
LPWSTR pwszColumnName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
// DBKIND_GUID_NAME
|
|
// DBKIND_GUID_PROPID
|
|
// DBKIND_NAME
|
|
// DBKIND_PGUID_NAME
|
|
// DBKIND_PGUID_PROPID
|
|
// DBKIND_PROPID
|
|
// DBKIND_GUID
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
pwszColumnName = rgColumnDesc[0].dbcid.uName.pwszName;
|
|
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszColumnName;
|
|
TEST2C_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK, DB_E_BADCOLUMNID);
|
|
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_GUID_NAME;
|
|
rgColumnDesc[0].dbcid.uGuid.guid = guidModule;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszColumnName;
|
|
TEST2C_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK, DB_E_BADCOLUMNID);
|
|
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_PGUID_NAME;
|
|
rgColumnDesc[0].dbcid.uGuid.pguid = &guidModule;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszColumnName;
|
|
TEST2C_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK, DB_E_BADCOLUMNID);
|
|
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_GUID;
|
|
rgColumnDesc[0].dbcid.uGuid.guid = guidModule;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszColumnName;
|
|
TEST2C_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK, DB_E_BADCOLUMNID);
|
|
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_GUID_PROPID;
|
|
rgColumnDesc[0].dbcid.uGuid.guid = guidModule;
|
|
rgColumnDesc[0].dbcid.uName.ulPropid = 0xffL;
|
|
TEST2C_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK, DB_E_BADCOLUMNID);
|
|
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_PGUID_PROPID;
|
|
rgColumnDesc[0].dbcid.uGuid.pguid = &guidModule;
|
|
rgColumnDesc[0].dbcid.uName.ulPropid = 0xffL;
|
|
TEST2C_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK, DB_E_BADCOLUMNID);
|
|
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_PROPID;
|
|
rgColumnDesc[0].dbcid.uGuid.pguid = &guidModule;
|
|
rgColumnDesc[0].dbcid.uName.ulPropid = 0xffL;
|
|
TEST2C_(CCNDropTable(NULL, cColumnDesc, rgColumnDesc, IID_IRowset, 0, NULL), S_OK, DB_E_BADCOLUMNID);
|
|
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = pwszColumnName;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCCreateTable::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(RODataSource)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: RODataSource - Test case for operating on a read only data source
|
|
//| Created: 10/13/97
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL RODataSource::Init()
|
|
{
|
|
BOOL fResults = TEST_SKIPPED;
|
|
IDBInitialize *pIDBInitialize = NULL;
|
|
IDBProperties *pIDBProperties = NULL;
|
|
DBPROPSET *rgPropSets = NULL;
|
|
ULONG cPropSets = 0;
|
|
HRESULT hr = NOERROR;
|
|
DBPROP *rgProperties = NULL;
|
|
const int n=1;
|
|
const ULONG nINIT_MODE = 0;
|
|
DBPROPIDSET rgPropIDSet[n];
|
|
DBPROPID rgPropID1[1];
|
|
ULONG nActualSize = n;
|
|
|
|
m_pIUnknown = NULL;
|
|
m_pIUnknown2 = NULL;
|
|
m_pITableDefinition2 = NULL;
|
|
m_pTable = NULL;
|
|
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(!TCDropColumn::Init())
|
|
// }}
|
|
goto CLEANUP2;
|
|
|
|
if (!SettableProperty(DBPROP_INIT_MODE, DBPROPSET_DBINIT))
|
|
{
|
|
odtLog << "DBPROP_INIT_MODE is not supported or is not a read-write property\n";
|
|
fResults = TEST_SKIPPED;
|
|
goto CLEANUP2;
|
|
}
|
|
|
|
// create a spare table on the read-write datasource
|
|
m_hr = m_pTable->CreateTable(10, 0);
|
|
|
|
m_pITableDefinition2 = m_pITableDefinition;
|
|
m_pITableDefinition = NULL;
|
|
fResults = FALSE;
|
|
|
|
if (!CHECK(m_hr, S_OK))
|
|
{
|
|
odtLog << "could not create atable on the read-write data source!\n";
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// Setup the arrays needed for init, based on string LTM passed to us
|
|
if(!GetInitProps(&cPropSets, &rgPropSets))
|
|
goto CLEANUP;
|
|
|
|
|
|
// Get our initial connection to the provider, asking for IDBInitialize since
|
|
// we must initialize before anything else
|
|
if(!SUCCEEDED(m_hr = GetModInfo()->CreateProvider(NULL, IID_IDBInitialize, (IUnknown**)&pIDBInitialize)))
|
|
goto CLEANUP;
|
|
|
|
// Get IDBProperties Pointer
|
|
pIDBProperties = NULL;
|
|
if (!VerifyInterface(pIDBInitialize, IID_IDBProperties, DATASOURCE_INTERFACE, (IUnknown**)&pIDBProperties))
|
|
goto CLEANUP;
|
|
|
|
// Set the properties before we Initialize, only if we have Properties to set...
|
|
if (FAILED(m_hr = pIDBProperties->SetProperties(cPropSets, rgPropSets)))
|
|
goto CLEANUP;
|
|
|
|
// free the structures
|
|
FreeProperties(&cPropSets, &rgPropSets);
|
|
rgPropSets = NULL;
|
|
cPropSets = 0;
|
|
SetProperty(&rgPropSets, &cPropSets, DBPROP_INIT_MODE, VT_I4, (LPVOID)DB_MODE_READ, DBPROPOPTIONS_REQUIRED, DB_NULLID,
|
|
DBPROPSET_DBINIT);
|
|
// Set the properties before we Initialize, only if we have Properties to set...
|
|
if (FAILED(m_hr = pIDBProperties->SetProperties(cPropSets, rgPropSets)))
|
|
{
|
|
FindProperty(
|
|
DBPROP_INIT_MODE,
|
|
DBPROPSET_DBINIT,
|
|
cPropSets,
|
|
rgPropSets,
|
|
&rgProperties);
|
|
if (DBPROPSTATUS_OK != rgProperties->dwStatus)
|
|
odtLog << "Read only property could not be initialized!\n";
|
|
goto CLEANUP1;
|
|
}
|
|
else
|
|
{
|
|
PRVTRACE("RODataSource::Init(): Apparently the read only property was set\n");
|
|
FindProperty(
|
|
DBPROP_INIT_MODE,
|
|
DBPROPSET_DBINIT,
|
|
cPropSets,
|
|
rgPropSets,
|
|
&rgProperties);
|
|
if (DBPROPSTATUS_OK != rgProperties->dwStatus)
|
|
odtLog << "ERROR: Read only property could not be initialized in fact!\n";
|
|
}
|
|
FreeProperties( &cPropSets, &rgPropSets);
|
|
|
|
// Initialize
|
|
if(!GCHECK(m_hr = pIDBInitialize->Initialize(), S_OK))
|
|
{
|
|
odtLog << wszInitializeFailed;
|
|
goto CLEANUP1;
|
|
}
|
|
|
|
// check that the read only property was set
|
|
rgPropID1[0] = DBPROP_INIT_MODE;
|
|
rgPropIDSet[nINIT_MODE].cPropertyIDs = 1;
|
|
rgPropIDSet[nINIT_MODE].rgPropertyIDs = rgPropID1;
|
|
rgPropIDSet[nINIT_MODE].guidPropertySet = DBPROPSET_DBINIT;
|
|
|
|
CHECK(m_hr = pIDBProperties->GetProperties(nActualSize, rgPropIDSet, &cPropSets, &rgPropSets), S_OK);
|
|
if ( (DBPROPSTATUS_OK == rgPropSets[nINIT_MODE].rgProperties[0].dwStatus)
|
|
&& ( (VT_I4 != rgPropSets[nINIT_MODE].rgProperties[0].vValue.vt)
|
|
|| (DB_MODE_READ != V_I4(&rgPropSets[nINIT_MODE].rgProperties[0].vValue))))
|
|
{
|
|
odtLog << "despite ok reports, DBPROP_INIT_MODE is not set to read only\n";
|
|
goto CLEANUP1;
|
|
}
|
|
|
|
// Obtain IDBCreateSesson, placing the new DSO interface
|
|
// in CThisTestModule's m_pIUnknown, so that all testcases can use
|
|
// it via their back pointer to this object. No need to call AddRef
|
|
// here as we will own it, rather than the test module.
|
|
if (!VerifyInterface(pIDBInitialize, IID_IDBCreateSession, DATASOURCE_INTERFACE,
|
|
(IUnknown**)&m_pIUnknown))
|
|
goto CLEANUP1;
|
|
|
|
// Create a DB session object
|
|
// Set the m_pIUnknown2 to IOpenRowset
|
|
if (!GCHECK(((IDBCreateSession*)m_pIUnknown)->CreateSession(
|
|
NULL, IID_IOpenRowset, (IUnknown **)&m_pIUnknown2), S_OK))
|
|
goto CLEANUP1;
|
|
|
|
SetDBSession(m_pIUnknown2); // calls ReleaseDBSession Before
|
|
// switch the interface on ItableDefinition
|
|
if (!(m_hr=VerifyInterface(m_pIUnknown2, IID_ITableDefinition, SESSION_INTERFACE,
|
|
(IUnknown**)&m_pITableDefinition)))
|
|
goto CLEANUP1;
|
|
|
|
fResults = TRUE;
|
|
CLEANUP1:
|
|
FreeProperties( &cPropSets, &rgPropSets);
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBProperties);
|
|
SAFE_RELEASE(pIDBInitialize);
|
|
return fResults;
|
|
|
|
CLEANUP2:
|
|
if (m_pITableDefinition)
|
|
{
|
|
m_pITableDefinition2 = m_pITableDefinition;
|
|
m_pITableDefinition = NULL;
|
|
}
|
|
return fResults;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add a column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int RODataSource::Variation_1()
|
|
{
|
|
|
|
BOOL fResults = TEST_PASS;
|
|
DBID *pColumnID = NULL;
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = m_pTable->CountColumnsOnTable();
|
|
|
|
m_pTable->BuildColumnDescs(&rgColumnDesc);
|
|
TESTC(0 < cColumnDesc);
|
|
|
|
PROVIDER_FREE(rgColumnDesc->dbcid.uName.pwszName);
|
|
FreeProperties( &rgColumnDesc->cPropertySets, &rgColumnDesc->rgPropertySets);
|
|
rgColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"newColumn");
|
|
|
|
if (!CHECK(hr = m_pITableDefinition->AddColumn(&m_pTable->GetTableID(), rgColumnDesc, &pColumnID),
|
|
DB_SEC_E_PERMISSIONDENIED))
|
|
fResults = TEST_FAIL;
|
|
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
CLEANUP:
|
|
return fResults;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int RODataSource::Variation_2()
|
|
{
|
|
TBEGIN;
|
|
DBID ColumnID;
|
|
DBCOLUMNDESC *oldCD = NULL;
|
|
DBORDINAL oldlen = 0;
|
|
|
|
GetColumnDescOnTable(&m_pTable->GetTableID(), &oldCD, &oldlen);
|
|
TESTC_PROVIDER(1 < oldlen);
|
|
|
|
ColumnID.eKind = DBKIND_NAME;
|
|
ColumnID.uName.pwszName = oldCD[0].dbcid.uName.pwszName;
|
|
TEST2C_(DropColumnAndCheck(&m_pTable->GetTableID(), &ColumnID), S_OK, DB_SEC_E_PERMISSIONDENIED);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(oldCD, oldlen);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int RODataSource::Variation_3()
|
|
{
|
|
BOOL fResults = TEST_PASS;
|
|
DBID *pTableID = NULL;
|
|
|
|
if (!CHECK(m_pITableDefinition->CreateTable(NULL, NULL, m_cColumnDesc, m_rgColumnDesc,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_SEC_E_PERMISSIONDENIED))
|
|
{
|
|
fResults = TEST_FAIL;
|
|
m_pITableDefinition->DropTable(pTableID);
|
|
}
|
|
ReleaseDBID(pTableID);
|
|
return fResults;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int RODataSource::Variation_4()
|
|
{
|
|
BOOL fResults = TEST_PASS;
|
|
BOOL fExists;
|
|
|
|
if ( !CHECK(m_pITableDefinition->DropTable(&m_pTable->GetTableID()), DB_SEC_E_PERMISSIONDENIED)
|
|
|| !CHECK(m_pTable->DoesTableExist(&m_pTable->GetTableID(), &fExists), S_OK)
|
|
|| !fExists)
|
|
fResults = TEST_FAIL;
|
|
return fResults;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL RODataSource::Terminate()
|
|
{
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
SAFE_RELEASE(m_pITableDefinition);
|
|
m_pITableDefinition = m_pITableDefinition2;
|
|
m_pITableDefinition2 = NULL;
|
|
SetDBSession(m_pITableDefinition);
|
|
if (m_pTable)
|
|
{
|
|
m_hr = m_pTable->DropTable();
|
|
delete m_pTable;
|
|
m_pTable = NULL;
|
|
}
|
|
return(TCDropColumn::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
// Hack to defile CoInitializeEx
|
|
WINOLEAPI CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
|
|
|
|
unsigned WINAPI ThreadProc(LPVOID lpvThreadParam)
|
|
{
|
|
CoInitializeEx(NULL, 0);
|
|
TCITableDefinition *pObject = ((CInParam*)lpvThreadParam)->pObject;
|
|
pObject->MyThreadProc(((CInParam*)lpvThreadParam)->i);
|
|
CoUninitialize();
|
|
return 1;
|
|
} //ThreadProc
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAddConstraint_Boundary)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAddConstraint_Boundary - General and boundary/null test for ITableDefinitionWithConstraints::AddConstraint
|
|
//| Created: 7/29/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddConstraint_Boundary::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL || GetModInfo()->GetClassContext()==CLSCTX_LOCAL_SERVER)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Check the session object (QI for interfaces)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_1()
|
|
{
|
|
return DefaultObjectTesting(m_pThisTestModule->m_pIUnknown2, SESSION_INTERFACE);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_2()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
consCheck.SetConstraintText(L"TRUE != FALSE");
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, NULL, consFK), E_INVALIDARG);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, NULL, consPK), E_INVALIDARG);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, NULL, consUnique), E_INVALIDARG);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, NULL, consCheck), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pTableID is DB_NULLID => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBID TableID;
|
|
|
|
DuplicateDBID(DB_NULLID, &TableID);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, rgBaseCol[0], 12), S_OK);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consFK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consPK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consUnique), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consCheck), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table name is NULL => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBID TableID;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, rgBaseCol[0], 12), S_OK);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consFK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consPK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consUnique), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consCheck), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table name is the empty string => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_5()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBID TableID;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, rgBaseCol[0], 17), S_OK);
|
|
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = wcsDuplicate(L"");
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consFK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consPK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consUnique), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consCheck), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table name has maximum length
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_6()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBID TableID;
|
|
|
|
// create a table with maximum length
|
|
BaseTable.MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = BuildValidName(m_cMaxTableName, BaseTable.GetTableName());
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0, TableID.uName.pwszName), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, rgBaseCol[0], 12), S_OK);
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &TableID, consFK), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &TableID, consPK), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &TableID, consUnique), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &TableID, consCheck), S_OK);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table name exceeds maximum length => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_7()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBID TableID;
|
|
|
|
// create a table with maximum length
|
|
BaseTable.MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = BuildValidName(m_cMaxTableName+1, BaseTable.GetTableName());
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, rgBaseCol[0], 12), S_OK);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consFK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consPK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consUnique), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consCheck), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table name contains illegal characters
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_8()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBID TableID;
|
|
size_t m, n;
|
|
|
|
// create a table with maximum length
|
|
BaseTable.MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
m = min(m_cMaxTableName, n=5+wcslen(BaseTable.GetTableName()));
|
|
TableID.uName.pwszName = BuildInvalidName(m, BaseTable.GetTableName(), m_pwszInvalidTableChars);
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, rgBaseCol[0], 12), S_OK);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consFK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consPK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consUnique), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consCheck), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid DBKIND value for the base table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_9()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBID TableID;
|
|
|
|
// create a table with maximum length
|
|
BaseTable.MakeTableName(NULL);
|
|
memset(&TableID, 0, sizeof(DBID));
|
|
TableID.eKind = 0xce;
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, rgBaseCol[0], 12), S_OK);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consFK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consPK), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consUnique), DB_E_NOTABLE);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &TableID, consCheck), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL column list in a constraint, column size is not 0 => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_10()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1, 2, 3};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBCONSTRAINTDESC *pConsDesc;
|
|
DBID *p1 = NULL, *p2 = NULL;
|
|
|
|
// create a table with maximum length
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consUnique;
|
|
p1 = pConsDesc->rgColumnList;
|
|
pConsDesc->rgColumnList = NULL;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), E_INVALIDARG);
|
|
pConsDesc->rgColumnList = p1;
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consPK;
|
|
p1 = pConsDesc->rgColumnList;
|
|
pConsDesc->rgColumnList = NULL;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), E_INVALIDARG);
|
|
pConsDesc->rgColumnList = p1;
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
p1 = pConsDesc->rgColumnList;
|
|
pConsDesc->rgColumnList = NULL;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), E_INVALIDARG);
|
|
|
|
p2 = pConsDesc->rgForeignKeyColumnList;
|
|
pConsDesc->rgForeignKeyColumnList = NULL;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), E_INVALIDARG);
|
|
|
|
pConsDesc->rgColumnList = p1;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), E_INVALIDARG);
|
|
pConsDesc->rgColumnList = p1;
|
|
pConsDesc->rgForeignKeyColumnList = p2;
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL column name in a constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_11()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1, 2, 3};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBCONSTRAINTDESC *pConsDesc;
|
|
|
|
// create a table with maximum length
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgColumnList[1].uName.pwszName = NULL;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgColumnList[1].uName.pwszName = NULL;
|
|
ReleaseDBID(&pConsDesc->rgForeignKeyColumnList[2], FALSE);
|
|
pConsDesc->rgForeignKeyColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgForeignKeyColumnList[1].uName.pwszName = NULL;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgForeignKeyColumnList[1], FALSE);
|
|
pConsDesc->rgForeignKeyColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgForeignKeyColumnList[1].uName.pwszName = NULL;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consUnique;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgColumnList[1].uName.pwszName = NULL;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_NOCOLUMN);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consPK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgColumnList[1].uName.pwszName = NULL;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty string for a column name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1, 2, 3};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBCONSTRAINTDESC *pConsDesc;
|
|
|
|
// create a table with maximum length
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgColumnList[1].uName.pwszName = wcsDuplicate(L"");
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgColumnList[1].uName.pwszName = wcsDuplicate(L"");
|
|
ReleaseDBID(&pConsDesc->rgForeignKeyColumnList[2], FALSE);
|
|
pConsDesc->rgForeignKeyColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgForeignKeyColumnList[1].uName.pwszName = wcsDuplicate(L"");
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgForeignKeyColumnList[1], FALSE);
|
|
pConsDesc->rgForeignKeyColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgForeignKeyColumnList[1].uName.pwszName = wcsDuplicate(L"");
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consUnique;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgColumnList[1].uName.pwszName = wcsDuplicate(L"");
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_NOCOLUMN);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consPK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = DBKIND_NAME;
|
|
pConsDesc->rgColumnList[1].uName.pwszName = wcsDuplicate(L"");
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length column name in a constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_13()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
|
|
WCHAR *pwszName = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
BaseTable.SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
BaseTable.SetBuildColumnDesc(FALSE);
|
|
BaseTable.MakeTableName(NULL);
|
|
pwszName = wcsDuplicate(BaseTable.GetTableName());
|
|
|
|
if (rgColumnDesc[0].dbcid.uName.pwszName)
|
|
SAFE_FREE(rgColumnDesc[0].dbcid.uName.pwszName);
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = BuildValidName(m_cMaxColName, pwszName);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&ReferencedTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, rgCol[0], 12), S_OK);
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszName);
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Column name exceeds maximum length
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_14()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
|
|
WCHAR *pwszName = NULL;
|
|
WCHAR *pwszColName = NULL;
|
|
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DBCONSTRAINTDESC *pConsDesc;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
BaseTable.SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
BaseTable.SetBuildColumnDesc(FALSE);
|
|
BaseTable.MakeTableName(NULL);
|
|
pwszName = wcsDuplicate(BaseTable.GetTableName());
|
|
|
|
if (rgColumnDesc[0].dbcid.uName.pwszName)
|
|
SAFE_FREE(rgColumnDesc[0].dbcid.uName.pwszName);
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = BuildValidName(m_cMaxColName, pwszName);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
pwszColName = BuildValidName(m_cMaxColName+1, pwszName);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&ReferencedTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
SAFE_FREE(pConsDesc->rgForeignKeyColumnList[0].uName.pwszName);
|
|
pConsDesc->rgForeignKeyColumnList[0].uName.pwszName = wcsDuplicate(pwszColName);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
pConsDesc = consUnique;
|
|
SAFE_FREE(pConsDesc->rgColumnList[0].uName.pwszName);
|
|
pConsDesc->rgColumnList[0].uName.pwszName = wcsDuplicate(pwszColName);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
pConsDesc = consPK;
|
|
SAFE_FREE(pConsDesc->rgColumnList[0].uName.pwszName);
|
|
pConsDesc->rgColumnList[0].uName.pwszName = wcsDuplicate(pwszColName);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetIsNotNULLCheckConstraint(pwszColName), S_OK);
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_NOCOLUMN);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_NOCOLUMN);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), E_FAIL);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszColName);
|
|
SAFE_FREE(pwszName);
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid DBKIND for a column DBID of a constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_15()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1, 2, 3};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBCONSTRAINTDESC *pConsDesc;
|
|
|
|
// create a table with maximum length
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = 0xfe;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = 0xfe;
|
|
ReleaseDBID(&pConsDesc->rgForeignKeyColumnList[2], FALSE);
|
|
pConsDesc->rgForeignKeyColumnList[1].eKind = 0xfe;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgForeignKeyColumnList[1], FALSE);
|
|
pConsDesc->rgForeignKeyColumnList[1].eKind = 0xfe;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consUnique;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = 0xee;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_NOCOLUMN);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consPK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
pConsDesc->rgColumnList[1].eKind = 0xac;
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Column ID is DB_NULLID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_16()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1, 2, 3};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBCONSTRAINTDESC *pConsDesc;
|
|
|
|
// create a table with maximum length
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
DuplicateDBID(DB_NULLID, &pConsDesc->rgColumnList[1]);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
DuplicateDBID(DB_NULLID, &pConsDesc->rgColumnList[1]);
|
|
ReleaseDBID(&pConsDesc->rgForeignKeyColumnList[2], FALSE);
|
|
DuplicateDBID(DB_NULLID, &pConsDesc->rgForeignKeyColumnList[1]);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
pConsDesc = consFK;
|
|
ReleaseDBID(&pConsDesc->rgForeignKeyColumnList[1], FALSE);
|
|
DuplicateDBID(DB_NULLID, &pConsDesc->rgForeignKeyColumnList[1]);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consUnique;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
memset(&pConsDesc->rgColumnList[1], 0, sizeof(DBID));
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_NOCOLUMN);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pConsDesc = consPK;
|
|
ReleaseDBID(&pConsDesc->rgColumnList[1], FALSE);
|
|
memset(&pConsDesc->rgColumnList[1], 0, sizeof(DBID));
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL pReferencedTableID for a foreign key constraint (with and without cForeignKeyColumns being 0)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_17()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
|
|
// create the referenced table in this catalog
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.CreateTable(0, 0));
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// create the
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType), S_OK);
|
|
consFK.SetReferencedTableID(NULL);
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CHECK(consFK.ReleaseForeignKeyColumnList(), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBNULL_ID *pReferencedTableID for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_18()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
|
|
// create the referenced table in this catalog
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.CreateTable(0, 0));
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// create the constraint
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType), S_OK);
|
|
consFK.SetReferencedTableID((DBID*)&DB_NULLID);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL referenced table name for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_19()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
DBID ReferencedTableID;
|
|
|
|
// create the referenced table in this catalog
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.CreateTable(0, 0));
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// create the
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType), S_OK);
|
|
ReferencedTableID.eKind = DBKIND_NAME;
|
|
ReferencedTableID.uName.pwszName = NULL;
|
|
consFK.SetReferencedTableID(&ReferencedTableID);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Emptry string referenced table name for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_20()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
DBID ReferencedTableID;
|
|
|
|
// create the referenced table in this catalog
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.CreateTable(0, 0));
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// create the constraint
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType), S_OK);
|
|
ReferencedTableID.eKind = DBKIND_NAME;
|
|
ReferencedTableID.uName.pwszName = L"";
|
|
consFK.SetReferencedTableID(&ReferencedTableID);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length referenced table name for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_21()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
WCHAR *pwszTableName = NULL;
|
|
|
|
// create the referenced table in this catalog
|
|
// create a table with maximum length
|
|
ReferencedTable.MakeTableName(NULL);
|
|
pwszTableName = BuildValidName(m_cMaxTableName, ReferencedTable.GetTableName());
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.CreateTable(0, 0, pwszTableName));
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// create the
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType), S_OK);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszTableName);
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Referenced table name longer than allowed for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_22()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
WCHAR *pwszTableName = NULL;
|
|
DBCONSTRAINTDESC *pConsDesc = consFK;
|
|
|
|
// create the referenced table in this catalog
|
|
// create a table with maximum length
|
|
ReferencedTable.MakeTableName(NULL);
|
|
pwszTableName = BuildValidName(m_cMaxTableName, ReferencedTable.GetTableName());
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.CreateTable(0, 0, pwszTableName));
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// create the
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType), S_OK);
|
|
SAFE_FREE(pwszTableName);
|
|
ReleaseDBID(pConsDesc->pReferencedTableID, FALSE);
|
|
pConsDesc->pReferencedTableID->eKind = DBKIND_NAME;
|
|
pConsDesc->pReferencedTableID->uName.pwszName = BuildValidName(m_cMaxTableName + 1, ReferencedTable.GetTableName());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszTableName);
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Illegal characters in the referenced table name for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_23()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
DBID ReferencedTableID;
|
|
size_t m, n;
|
|
|
|
// create the referenced table in this catalog
|
|
// create a table with maximum length
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.CreateTable(0, 0));
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// create the constraint
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType), S_OK);
|
|
m = min(m_cMaxTableName, n=5+wcslen(ReferencedTable.GetTableName()));
|
|
ReferencedTableID.uName.pwszName = BuildInvalidName(m, ReferencedTable.GetTableName(), m_pwszInvalidTableChars);
|
|
consFK.SetReferencedTableID(&ReferencedTableID);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
ReleaseDBID(&ReferencedTableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad constraint type
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_24()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CConsDesc cons((DBCONSTRAINTTYPE)0xfd);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), DB_E_BADCONSTRAINTTYPE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty list of columns for a unique, primay key or foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_25()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR *pwszColValue = NULL;
|
|
CCol col;
|
|
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&ReferencedTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
consFK.ReleaseColumnList();
|
|
TEST2C_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), E_INVALIDARG, DB_E_BADCONSTRAINTFORM);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&ReferencedTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
consFK.ReleaseForeignKeyColumnList();
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_BADCONSTRAINTFORM);
|
|
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&ReferencedTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
consFK.ReleaseForeignKeyColumnList();
|
|
consFK.ReleaseColumnList();
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_BADCONSTRAINTFORM);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
consUnique.ReleaseColumnList();
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_BADCONSTRAINTFORM);
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
consPK.ReleaseColumnList();
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Non empty list of columns for a check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_26()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CCheckCons consCheck;
|
|
DBCONSTRAINTDESC *pcons = consCheck;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR *pwszColValue = NULL;
|
|
CCol col;
|
|
DBID rgColList;
|
|
DBID rgForeignKeyColList;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetLTCheckConstraint(&BaseTable, 1, 12), S_OK);
|
|
|
|
DuplicateDBID(*col.GetColID(), &rgColList);
|
|
DuplicateDBID(*col.GetColID(), &rgForeignKeyColList);
|
|
|
|
// not empty rgColumnList
|
|
pcons->cColumns = 1;
|
|
pcons->rgColumnList = &rgColList;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), DB_E_BADCONSTRAINTFORM);
|
|
|
|
// not empty rgForeignKeyColumnList
|
|
pcons->cColumns = 0;
|
|
pcons->rgColumnList = NULL;
|
|
pcons->cForeignKeyColumns = 1;
|
|
pcons->rgForeignKeyColumnList = &rgForeignKeyColList;
|
|
hr = AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck);
|
|
// since the number of columns is different from the number of foreign key columns
|
|
// E_INVALIDARG can be returned as well
|
|
if (E_INVALIDARG != hr)
|
|
CHECK(hr, DB_E_BADCONSTRAINTFORM);
|
|
|
|
// not empty rgColumnList and rgForeignKeyColumnList
|
|
pcons->cColumns = 1;
|
|
pcons->rgColumnList = &rgColList;
|
|
pcons->cForeignKeyColumns = 1;
|
|
pcons->rgForeignKeyColumnList = &rgForeignKeyColList;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
pcons->cColumns = 0;
|
|
pcons->rgColumnList = NULL;
|
|
pcons->cForeignKeyColumns = 0;
|
|
pcons->rgForeignKeyColumnList = NULL;
|
|
ReleaseDBID(&rgColList, FALSE);
|
|
ReleaseDBID(&rgForeignKeyColList, FALSE);
|
|
SAFE_FREE(pwszConstraintText);
|
|
SAFE_FREE(pwszColValue);
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Not null pwszConstraintText in a unique, PK or FK constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_27()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
DBCONSTRAINTDESC *pcons;
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol, m_SupportedMatchType), S_OK);
|
|
pcons = consFK;
|
|
pcons->pwszConstraintText = L"fdfd";
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pcons = consUnique;
|
|
pcons->pwszConstraintText = L"fdfd";
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
pcons = consPK;
|
|
pcons->pwszConstraintText = L"fdfd";
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_BADCONSTRAINTFORM);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_BADCONSTRAINTFORM);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
pcons = consFK;
|
|
pcons->pwszConstraintText = NULL;
|
|
pcons = consPK;
|
|
pcons->pwszConstraintText = NULL;
|
|
pcons = consUnique;
|
|
pcons->pwszConstraintText = NULL;
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL pConstraintDesc => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_28()
|
|
{
|
|
TBEGIN
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &m_pTable->GetTableID(), NULL), E_INVALIDARG);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 0 < cColumns and NULL == rgColumnList => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_29()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
CHECK(consFK.ReleaseColumnList(), S_OK);
|
|
((DBCONSTRAINTDESC*)consFK)->cColumns = 3;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), E_INVALIDARG);
|
|
((DBCONSTRAINTDESC*)consFK)->cColumns = 0;
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
CHECK(consUnique.ReleaseColumnList(), S_OK);
|
|
((DBCONSTRAINTDESC*)consUnique)->cColumns = 3;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), E_INVALIDARG);
|
|
((DBCONSTRAINTDESC*)consUnique)->cColumns = 0;
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
CHECK(consPK.ReleaseColumnList(), S_OK);
|
|
((DBCONSTRAINTDESC*)consPK)->cColumns = 3;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), E_INVALIDARG);
|
|
((DBCONSTRAINTDESC*)consPK)->cColumns = 0;
|
|
|
|
// set up the check constraint
|
|
consCheck.SetConstraintText(L"TRUE != FALSE");
|
|
((DBCONSTRAINTDESC*)consCheck)->cColumns = 3;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), E_INVALIDARG);
|
|
((DBCONSTRAINTDESC*)consCheck)->cColumns = 0;
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 0 < cForeignKeyColumns and NULL == rgForeignKeyColumnList => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_30()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgBaseCol), rgBaseCol, m_SupportedMatchType), S_OK);
|
|
CHECK(consFK.ReleaseForeignKeyColumnList(), S_OK);
|
|
((DBCONSTRAINTDESC*)consFK)->cForeignKeyColumns = 3;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), E_INVALIDARG);
|
|
((DBCONSTRAINTDESC*)consFK)->cForeignKeyColumns = 0;
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
((DBCONSTRAINTDESC*)consUnique)->cForeignKeyColumns = 3;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), E_INVALIDARG);
|
|
((DBCONSTRAINTDESC*)consUnique)->cForeignKeyColumns = 0;
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
((DBCONSTRAINTDESC*)consPK)->cForeignKeyColumns = 3;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), E_INVALIDARG);
|
|
((DBCONSTRAINTDESC*)consPK)->cForeignKeyColumns = 0;
|
|
|
|
// set up the check constraint
|
|
consCheck.SetConstraintText(L"TRUE != FALSE");
|
|
((DBCONSTRAINTDESC*)consCheck)->cForeignKeyColumns = 3;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), E_INVALIDARG);
|
|
((DBCONSTRAINTDESC*)consCheck)->cForeignKeyColumns = 0;
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Constraint is not foreign key and pReferencedTableID is not NULL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_31()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBID ReferencedTableID;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR *pwszColValue = NULL;
|
|
CCol col;
|
|
ReferencedTableID.eKind = DBKIND_NAME;
|
|
ReferencedTableID.uName.pwszName = (LPWSTR)0x01234567;
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
((DBCONSTRAINTDESC*)consUnique)->pReferencedTableID = &ReferencedTableID;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consUnique)->pReferencedTableID = NULL;
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
((DBCONSTRAINTDESC*)consPK)->pReferencedTableID = &ReferencedTableID;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consPK)->pReferencedTableID = NULL;
|
|
|
|
// set up the check constraint
|
|
TESTC_(BaseTable.GetColInfo(rgBaseCol[0], col), S_OK);
|
|
TESTC_(BaseTable.GetLiteralAndValue(col, &pwszColValue, rand(), col.GetColNum(), PRIMARY), S_OK);
|
|
SAFE_FREE(pwszConstraintText);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(col.GetColName()) + wcslen(pwszColValue) + 3);
|
|
wcscpy(pwszConstraintText, col.GetColName());
|
|
wcscat(pwszConstraintText, L" < ");
|
|
wcscat(pwszConstraintText, pwszColValue);
|
|
consCheck.SetConstraintText(pwszConstraintText);
|
|
|
|
((DBCONSTRAINTDESC*)consCheck)->pReferencedTableID = &ReferencedTableID;
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consCheck)->pReferencedTableID = NULL;
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
SAFE_FREE(pwszColValue);
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Non empty list of foreign keys for a constraint that is not foreign key
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_32()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
const DBORDINAL cColumns = 2;
|
|
DBID rgColumnList[cColumns];
|
|
DBORDINAL rgBaseCol[cColumns] = {1, 2};
|
|
|
|
rgColumnList[0].eKind = DBKIND_NAME;
|
|
rgColumnList[0].uName.pwszName = (LPWSTR)0x01234567;
|
|
rgColumnList[1].eKind = 0xfe;
|
|
rgColumnList[1].uName.pwszName = (LPWSTR)0x01234567;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// set up the unique constraint
|
|
TESTC_(consUnique.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
((DBCONSTRAINTDESC*)consUnique)->cForeignKeyColumns = cColumns;
|
|
((DBCONSTRAINTDESC*)consUnique)->rgForeignKeyColumnList = rgColumnList;
|
|
hr = AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique);
|
|
CHECK(hr, DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consUnique)->cForeignKeyColumns = 0;
|
|
((DBCONSTRAINTDESC*)consUnique)->rgForeignKeyColumnList = NULL;
|
|
|
|
// set up the primary key constraint
|
|
TESTC_(consPK.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol), S_OK);
|
|
((DBCONSTRAINTDESC*)consPK)->cForeignKeyColumns = cColumns;
|
|
((DBCONSTRAINTDESC*)consPK)->rgForeignKeyColumnList = rgColumnList;
|
|
hr = AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK);
|
|
CHECK(hr, DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consPK)->cForeignKeyColumns = 0;
|
|
((DBCONSTRAINTDESC*)consPK)->rgForeignKeyColumnList = NULL;
|
|
|
|
// set up the check constraint
|
|
consCheck.SetConstraintText(L"TRUE != FALSE");
|
|
((DBCONSTRAINTDESC*)consCheck)->cForeignKeyColumns = cColumns;
|
|
((DBCONSTRAINTDESC*)consCheck)->rgForeignKeyColumnList = rgColumnList;
|
|
hr = AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck);
|
|
if (E_INVALIDARG != hr)
|
|
CHECK(hr, DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consCheck)->cForeignKeyColumns = 0;
|
|
((DBCONSTRAINTDESC*)consCheck)->rgForeignKeyColumnList = NULL;
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent referenced table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_33()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons cons;
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
// create a table
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC_(cons.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgReferencedCol), rgReferencedCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set referenced table to an inexistent table name
|
|
Table.MakeTableName(NULL);
|
|
cons.SetReferencedTableID(&Table.GetTableID());
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add several constraints to the table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_34()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
CCheckCons consCheck;
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
DBORDINAL rgCols[] = {1};
|
|
CCol col;
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
ReferencedTable.GetTableID().eKind? ReferencedTable.GetTableID().uName.pwszName: NULL);
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
BaseTable.GetTableID().eKind? BaseTable.GetTableID().uName.pwszName: NULL);
|
|
|
|
// set a unique constraint on the second column
|
|
CHECK(consUnique.SetConstraint(&BaseTable, 1, rgCols), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), S_OK);
|
|
|
|
// set a primary key on the first column of the table
|
|
CHECK(consPrimaryKey.SetConstraint(&BaseTable, 1, rgCols), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPrimaryKey), S_OK);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
TESTC_(BaseTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddForeignKeyColumn(col.GetColID());
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consForeignKey), S_OK);
|
|
|
|
TESTC_(consCheck.SetLTCheckConstraint(&BaseTable, 2, 3), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent table name => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_35()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
CForeignKeyCons consFK(NULL, m_SupportedMatchType);
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
|
|
CCol col;
|
|
|
|
DBID dbidInexistent;
|
|
|
|
dbidInexistent.eKind = DBKIND_NAME;
|
|
dbidInexistent.uName.pwszName = L"Inexistent";
|
|
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
TESTC_(ReferencedTable.GetColInfo(rgCol[0], col), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
consFK.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
consFK.AddColumn(col.GetColID());
|
|
consFK.AddForeignKeyColumn(col.GetColID());
|
|
|
|
// set up the unique constraint
|
|
consUnique.AddColumn(col.GetColID());
|
|
|
|
// set up the primary key constraint
|
|
consPK.AddColumn(col.GetColID());
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetIsNotNULLCheckConstraint(col.GetColID()->uName.pwszName), S_OK);
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &dbidInexistent, consFK), DB_E_NOTABLE);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &dbidInexistent, consPK), DB_E_NOTABLE);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &dbidInexistent, consUnique), DB_E_NOTABLE);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &dbidInexistent, consCheck), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent column name => DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Boundary::Variation_36()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DBID dbidInexistent;
|
|
|
|
dbidInexistent.eKind = DBKIND_NAME;
|
|
dbidInexistent.uName.pwszName = L"Inexistent";
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
BaseTable.SetColumnDesc(rgColumnDesc, cColumnDesc);
|
|
BaseTable.SetBuildColumnDesc(FALSE);
|
|
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(consFK.SetConstraint(&BaseTable, 0, NULL,
|
|
&ReferencedTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
consFK.AddForeignKeyColumn(&dbidInexistent);
|
|
|
|
// set up the unique constraint
|
|
consUnique.AddColumn(&dbidInexistent);
|
|
|
|
// set up the primary key constraint
|
|
consPK.AddColumn(&dbidInexistent);
|
|
|
|
// set up the check constraint
|
|
CHECK(consCheck.SetIsNotNULLCheckConstraint(dbidInexistent.uName.pwszName), S_OK);
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consFK), DB_E_NOCOLUMN);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consPK), DB_E_NOCOLUMN);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consUnique), DB_E_NOCOLUMN);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), consCheck), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAddConstraint_Boundary::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAddConstraint_UNIQUE)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAddConstraint_UNIQUE - Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_UNIQUE
|
|
//| Created: 7/29/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddConstraint_UNIQUE::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and try to apply the constraint on each column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_1()
|
|
{
|
|
TBEGIN
|
|
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL index;
|
|
CUniqueCons cons;
|
|
DBORDINAL cColCount = 0,
|
|
cTotalLength = 0,
|
|
start = 1,
|
|
cColsInTable = 0;
|
|
HRESULT hrExpected;
|
|
ULONG ulNumberOfTests = 0;
|
|
|
|
// create the base table
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// build the constraint
|
|
|
|
// try to set all the columns in the unique keyunique
|
|
// Step 1: Skip BLOBs and Variable length columns
|
|
// and set Unique constraint on fixed length columns.
|
|
// It should succeed.
|
|
cColsInTable = Table.CountColumnsOnTable();
|
|
|
|
while(start < cColsInTable) {
|
|
|
|
cons.ReleaseColumnList();
|
|
cTotalLength = 0;
|
|
hrExpected = S_OK;
|
|
|
|
for (index = start, cColCount = 0; index <= Table.CountColumnsOnTable() &&
|
|
cColCount < cMaxColsPerCons; index++)
|
|
{
|
|
CCol col;
|
|
DBORDINAL colSizeInBytes = 0; //how many bytes the column contributes into maximum size of constraint
|
|
|
|
TESTC_(Table.GetColInfo(index, col), S_OK);
|
|
|
|
// Note: col.GetColumnSize returns length for string data types and we need size in bytes
|
|
// so multiply ColumnSize by 2 for WSTR
|
|
if(col.GetIsFixedLength() )
|
|
colSizeInBytes = col.GetColumnSize() * (col.GetProviderType()==DBTYPE_WSTR ? 2:1);
|
|
else
|
|
colSizeInBytes = 0;
|
|
|
|
if (col.GetIsLong() ||
|
|
cTotalLength + colSizeInBytes > cMaxColLengthPerCons)
|
|
continue;
|
|
|
|
cTotalLength += colSizeInBytes;
|
|
cons.AddColumn(col.GetColID());
|
|
cColCount++;
|
|
}
|
|
|
|
if (cColCount)
|
|
{
|
|
ulNumberOfTests++;
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), hrExpected);
|
|
if (hrExpected == S_OK) {
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
}
|
|
}
|
|
|
|
start = index;
|
|
}
|
|
TESTC(ulNumberOfTests>0);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Set a unique constraint on each type of column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL index;
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
HRESULT hrExpected = S_OK;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
Table.BuildColumnDescs(&rgNewColumnDesc);
|
|
|
|
for (index=1; index <= Table.CountColumnsOnTable(); index++)
|
|
{
|
|
CCol col;
|
|
|
|
TESTC_(Table.GetColInfo(index, col), S_OK);
|
|
|
|
cons.ReleaseColumnList();
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
// Note: col.GetColumnSize returns length for string data types and we need size in bytes
|
|
// so multiply ColumnSize by 2 for WSTR
|
|
if (col.GetIsLong() ||
|
|
(col.GetIsFixedLength() && (col.GetColumnSize() * (col.GetProviderType()==DBTYPE_WSTR ? 2:1) > cMaxColLengthPerCons)))
|
|
hrExpected = E_FAIL;
|
|
else
|
|
hrExpected = S_OK;
|
|
|
|
|
|
odtLog << col.GetProviderTypeName() << "\t -> Expected: " << (hrExpected==S_OK ? "S_OK" : "E_FAIL") << "\n";
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), hrExpected);
|
|
if (hrExpected == S_OK) {
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
}
|
|
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), hrExpected);
|
|
if (hrExpected == S_OK) {
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a unique constraint that uses several columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL index;
|
|
DBORDINAL indxCol;
|
|
CUniqueCons cons;
|
|
DBORDINAL cCols;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
DBORDINAL cTotalLength = 0;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
Table.BuildColumnDescs(&rgNewColumnDesc);
|
|
|
|
cCols = 2 + rand() % __min(20, (Table.CountColumnsOnTable()-1));
|
|
|
|
for (index=0, indxCol=1; index < cCols && indxCol <= Table.CountColumnsOnTable(); indxCol++)
|
|
{
|
|
CCol col;
|
|
DBORDINAL colSizeInBytes = 0; //how many bytes the column contributes into maximum size of constraint
|
|
//make sure we have at least 2 columns before randomizing the rest
|
|
if ( cons.cColumns() < 2 || rand() % 2)
|
|
{
|
|
TESTC_(Table.GetColInfo(indxCol, col), S_OK);
|
|
|
|
// Note: col.GetColumnSize returns length for string data types and we need size in bytes
|
|
// so multiply ColumnSize by 2 for WSTR
|
|
if(col.GetIsFixedLength() )
|
|
colSizeInBytes = col.GetColumnSize() * (col.GetProviderType()==DBTYPE_WSTR ? 2:1);
|
|
else
|
|
colSizeInBytes = 0;
|
|
|
|
if (col.GetIsLong() ||
|
|
cTotalLength + colSizeInBytes > cMaxColLengthPerCons)
|
|
continue;
|
|
|
|
// put this column in the list
|
|
cTotalLength += colSizeInBytes;
|
|
|
|
cons.AddColumn(col.GetColID());
|
|
index++;
|
|
}
|
|
}
|
|
|
|
odtLog << "Constraint has " << cons.cColumns() << " columns\n";
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
// try the same when creating a table
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create several unique constraints on a table, no overlapping
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CUniqueCons cons2;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
TESTC_PROVIDER(4 <= Table.CountColumnsOnTable());
|
|
|
|
// choose 2 columns and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(4, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(Table.GetColInfo(2, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// choose another 2 columns and create a unique constraint
|
|
TESTC_(Table.GetColInfo(3, col), S_OK);
|
|
cons2.AddColumn(col.GetColID());
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
cons2.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons2), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create multiple, overlapping constraints on a table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_5()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CUniqueCons cons2;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
TESTC_PROVIDER(3 <= Table.CountColumnsOnTable());
|
|
|
|
// choose 2 columns and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(3, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(Table.GetColInfo(2, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// choose another 2 columns and create a unique constraint
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
cons2.AddColumn(col.GetColID());
|
|
TESTC_(Table.GetColInfo(3, col), S_OK);
|
|
cons2.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons2), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a constraint, drop it and recreate it
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_6()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint and recreate it
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a constraint on a null column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_7()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
// by setting DBCOLUMNDESC, all nullable type column are created as nullable
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// identify a nullable column
|
|
TESTC_PROVIDER(S_OK == Table.GetColInfo(IsCColNullable, col));
|
|
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a contraint on a not nullable column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_8()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// identify a nullable column
|
|
TESTC_PROVIDER(S_OK == Table.GetColInfo(IsCColNotNullable, col));
|
|
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// try the same when creating a table
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a constraint on a column that has a default value
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_9()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
VARIANT value;
|
|
DBORDINAL indexCol;
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
DBID *pTableID = NULL;
|
|
|
|
Table.CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
// by setting DBCOLUMNDESC, all nullable type column are created as nullable
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
// create a default value on one of the columns
|
|
VariantInit(&value);
|
|
indexCol = 2;
|
|
if (rgNewColumnDesc[indexCol-1].pwszTypeName)
|
|
odtLog << "Default value on type " << rgNewColumnDesc[indexCol-1].pwszTypeName << "\n";
|
|
GetDefaultValue(&rgNewColumnDesc[indexCol-1], &value, &Table);
|
|
SetDefaultProperty(&rgNewColumnDesc[indexCol-1].rgPropertySets, &rgNewColumnDesc[indexCol-1].cPropertySets,
|
|
&value, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&value);
|
|
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_PROVIDER(S_OK == Table.CreateTable(0, 0));
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// identify a nullable column
|
|
TESTC_(Table.GetColInfo(indexCol, col), S_OK);
|
|
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// try the same when creating a table
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a constraint on a column defined as a primary key
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_10()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBORDINAL indexCol;
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
DBID *pTableID = NULL;
|
|
|
|
Table.CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
// by setting DBCOLUMNDESC, all nullable type column are created as nullable
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
// create a default value on one of the columns
|
|
indexCol = 3;
|
|
if (rgNewColumnDesc[indexCol-1].pwszTypeName)
|
|
odtLog << "Default value on type " << rgNewColumnDesc[indexCol-1].pwszTypeName << "\n";
|
|
SetProperty(&rgNewColumnDesc[indexCol-1].rgPropertySets, &rgNewColumnDesc[indexCol-1].cPropertySets,
|
|
DBPROP_COL_PRIMARYKEY,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_PROVIDER(S_OK == Table.CreateTable(0, 0));
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// identify a nullable column
|
|
TESTC_(Table.GetColInfo(indexCol, col), S_OK);
|
|
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// try the same when creating a table
|
|
cons.MakeConstraintName();
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a constraint on a column defined as a foreign key
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_11()
|
|
{
|
|
TBEGIN
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col, col2;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBORDINAL indexCol;
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons cons2(NULL, m_SupportedMatchType);
|
|
DBCONSTRAINTDESC *pConsDesc2 = (DBCONSTRAINTDESC*)cons2;
|
|
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(RefTable.CountColumnsOnTable() == BaseTable.CountColumnsOnTable())
|
|
indexCol = 1;
|
|
TESTC_(RefTable.GetColInfo(indexCol, col2), S_OK);
|
|
TESTC_(BaseTable.GetColInfo(indexCol, col), S_OK);
|
|
|
|
TESTC_(AddUniqueConstraint(&RefTable, 1, &indexCol), S_OK);
|
|
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
// set column on base table
|
|
cons2.AddColumn(col2.GetColID());
|
|
|
|
// set foreign column
|
|
cons2.AddForeignKeyColumn(col.GetColID());
|
|
|
|
// set reference table
|
|
cons2.SetReferencedTableID(&RefTable.GetTableID());
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons2), S_OK);
|
|
|
|
// prepare and add the unique constraint on the column involved in a foreign key
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a constraint on a column that is included in an index
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
// create a table and an index
|
|
TESTC_(Table.CreateTable(0, 1), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// select a column (the one used in index)
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use the name of an already existing constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_13()
|
|
{
|
|
TBEGIN
|
|
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CUniqueCons UniqueCons;
|
|
CPrimaryKeyCons PKCons;
|
|
CCheckCons CheckCons;
|
|
CForeignKeyCons FKCons;
|
|
DBORDINAL rgCol[] = {1};
|
|
HRESULT hr;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
// create a table
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
// create a unique constraint
|
|
TESTC_(UniqueCons.SetConstraint(&Table, 1), S_OK);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), UniqueCons), S_OK);
|
|
|
|
// create a check constraint
|
|
CheckCons.SetLTCheckConstraint(&Table, 1, 60);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), CheckCons), S_OK);
|
|
|
|
// create a PK constraint
|
|
TESTC_(PKCons.SetConstraint(&Table, 1), S_OK);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), PKCons), S_OK);
|
|
|
|
// create a FK constraint
|
|
TESTC_(FKCons.SetConstraint(&Table, NUMELEM(rgCol), rgCol,
|
|
&ReferencedTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), FKCons), S_OK);
|
|
|
|
// add the constraint again, this time on other column (if possible)
|
|
TESTC_(cons.SetConstraint(&Table, 2), S_OK);
|
|
|
|
odtLog << "Unique constraint duplicate unique constraint name\n";
|
|
cons.SetConstraintID(UniqueCons.GetConstraintID());
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_DUPLICATECONSTRAINTID);
|
|
// try the same when creating a table
|
|
if (!CHECK(hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_DUPLICATECONSTRAINTID) && SUCCEEDED(hr))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
odtLog << "Unique constraint duplicate check constraint name\n";
|
|
cons.SetConstraintID(CheckCons.GetConstraintID());
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_DUPLICATECONSTRAINTID);
|
|
// try the same when creating a table
|
|
if (!CHECK(hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_DUPLICATECONSTRAINTID) && SUCCEEDED(hr))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
odtLog << "Unique constraint duplicate primary key constraint name\n";
|
|
cons.SetConstraintID(PKCons.GetConstraintID());
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_DUPLICATECONSTRAINTID);
|
|
// try the same when creating a table
|
|
if (!CHECK(hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_DUPLICATECONSTRAINTID) && SUCCEEDED(hr))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
odtLog << "Unique constraint duplicate foreign key constraint name\n";
|
|
cons.SetConstraintID(FKCons.GetConstraintID());
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_DUPLICATECONSTRAINTID);
|
|
// try the same when creating a table
|
|
if (!CHECK(hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_DUPLICATECONSTRAINTID) && SUCCEEDED(hr))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
CHECK(Table.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Constraint is created in a different catalog
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_14()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
DBCONSTRAINTDESC *pConsDesc = (DBCONSTRAINTDESC*)cons;
|
|
CCol col;
|
|
DBORDINAL indxCat = 0;
|
|
CCatalogs Catalogs(m_pIOpenRowset);
|
|
IDBProperties *pIDBProperties = NULL;
|
|
CPropSets PropSets;
|
|
WCHAR *pwszCurrentCatalog = NULL;
|
|
WCHAR *pwszQualTableName = NULL;
|
|
WCHAR *pwszCatalogName = NULL;
|
|
WCHAR *pwszSchemaName = NULL;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, m_pIDBInitialize));
|
|
TESTC_PROVIDER(1 < Catalogs.cCatalogs());
|
|
|
|
// create a table and an index
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// select column
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// set DBID of the table to its qualified form
|
|
TESTC(DBKIND_NAME == Table.GetTableID().eKind);
|
|
|
|
TESTC(GetCatalogSchemaNames(Table.GetTableName(), &pwszCatalogName, &pwszSchemaName));
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(m_pTable->GetQualifiedName(pwszCatalogName, pwszSchemaName, Table.GetTableName(), &pwszQualTableName),S_OK);
|
|
Table.SetTableName(pwszQualTableName);
|
|
|
|
// change the current catalog
|
|
TESTC(GetProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, m_pIDBInitialize,
|
|
&pwszCurrentCatalog));
|
|
TESTC(NULL != pwszCurrentCatalog);
|
|
|
|
TESTC(VerifyInterface(m_pIDBInitialize, IID_IDBProperties, DATASOURCE_INTERFACE, (IUnknown**)&pIDBProperties));
|
|
|
|
if (0 == wcscmp(pwszCurrentCatalog, Catalogs[0]))
|
|
indxCat++;
|
|
|
|
CHECK(PropSets.AddProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, VT_BSTR, (LPVOID)Catalogs[indxCat]), S_OK);
|
|
TESTC_PROVIDER(S_OK == pIDBProperties->SetProperties(PropSets, PropSets));
|
|
|
|
// alloc memory for column array
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
// try to make column unique
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
if (CHECK(PropSets.SetProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, VT_BSTR, (LPVOID)pwszCurrentCatalog), S_OK))
|
|
CHECK(pIDBProperties->SetProperties(PropSets, PropSets), S_OK);
|
|
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
SAFE_FREE(pwszQualTableName);
|
|
SAFE_FREE(pwszCurrentCatalog);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc create a unique constraint on a non empty table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_15()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table and an index
|
|
TESTC_(Table.CreateTable(10, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// select column
|
|
TESTC_(AddUniqueConstraint(&Table, 1), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a unique constraints on a column that has doubled values
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_16()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table and an index
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// double one of the rows
|
|
TESTC_PROVIDER(S_OK == Table.Insert(5));
|
|
TESTC_PROVIDER(S_OK == Table.Insert(5));
|
|
|
|
// add the constraint
|
|
TESTC_(AddUniqueConstraint(&Table, 1), DB_E_SCHEMAVIOLATION);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_17()
|
|
{
|
|
CAddUniqueConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort non retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_18()
|
|
{
|
|
CAddUniqueConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_19()
|
|
{
|
|
CAddUniqueConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit non retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_UNIQUE::Variation_20()
|
|
{
|
|
CAddUniqueConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
TRUE // Retaining
|
|
);
|
|
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
int TCAddConstraint_UNIQUE::Variation_21() {
|
|
TBEGIN
|
|
|
|
CLimitTable Table;
|
|
|
|
TESTC_(Table.CheckUniqueKeyLimit(), S_OK);
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAddConstraint_UNIQUE::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAddConstraint_PRIMARYKEY)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAddConstraint_PRIMARYKEY - Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_PRIMARYKEY
|
|
//| Created: 7/29/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddConstraint_PRIMARYKEY::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
// TO DO: Add your own code here
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and try to apply the constraint on each column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_1()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL index;
|
|
CPrimaryKeyCons cons;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
HRESULT hrExpected = S_OK;
|
|
DBORDINAL cColCount = 0,
|
|
cTotalLength = 0,
|
|
start = 1,
|
|
cTotalColsInTable = 0;
|
|
ULONG ulNumberOfTests = 0;
|
|
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
// create the base table
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// build the constraint
|
|
cTotalColsInTable = Table.CountColumnsOnTable();
|
|
|
|
while(start < cTotalColsInTable) {
|
|
|
|
cTotalLength = 0;
|
|
hrExpected = S_OK;
|
|
|
|
cons.ReleaseColumnList();
|
|
|
|
for (index = start, cColCount = 0; index <= Table.CountColumnsOnTable() &&
|
|
cColCount < cMaxColsPerCons; index++, cColCount++)
|
|
{
|
|
CCol col;
|
|
DBORDINAL colSizeInBytes = 0; //how many bytes the column contributes into maximum size of constraint
|
|
|
|
TESTC_(Table.GetColInfo(index, col), S_OK);
|
|
|
|
// Note: col.GetColumnSize returns length for string data types and we need size in bytes
|
|
// so multiply ColumnSize by 2 for WSTR
|
|
if(col.GetIsFixedLength() )
|
|
colSizeInBytes = col.GetColumnSize() * (col.GetProviderType()==DBTYPE_WSTR ? 2:1);
|
|
else
|
|
colSizeInBytes = 0;
|
|
|
|
if (col.GetIsLong() ||
|
|
cTotalLength + colSizeInBytes > cMaxColLengthPerCons)
|
|
continue;
|
|
|
|
cTotalLength += colSizeInBytes;
|
|
|
|
cons.AddColumn(col.GetColID());
|
|
}
|
|
|
|
if (cColCount)
|
|
{
|
|
ulNumberOfTests++;
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), hrExpected);
|
|
if (hrExpected == S_OK) {
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
}
|
|
|
|
// try the same when creating a table
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), hrExpected);
|
|
|
|
if (hrExpected==S_OK)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
}
|
|
|
|
start = index;
|
|
}
|
|
TESTC(ulNumberOfTests>0)
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Set a primary key constraint on each type of column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_2()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL index;
|
|
CPrimaryKeyCons cons;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
HRESULT hrExpected = S_OK;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// build the constraint
|
|
for (index=1; index <= Table.CountColumnsOnTable(); index++)
|
|
{
|
|
CCol col;
|
|
|
|
TESTC_(Table.GetColInfo(index, col), S_OK);
|
|
|
|
TESTC_(cons.ReleaseColumnList(), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
odtLog << col.GetProviderTypeName() << "\n";
|
|
|
|
// Depending on the type of column, set return value
|
|
|
|
// Note: col.GetColumnSize returns length for string data types and we need size in bytes
|
|
// so multiply ColumnSize by 2 for WSTR
|
|
if (col.GetIsLong() ||
|
|
(col.GetIsFixedLength() && (col.GetColumnSize() * (col.GetProviderType()==DBTYPE_WSTR ? 2:1) > cMaxColLengthPerCons)))
|
|
hrExpected = E_FAIL;
|
|
else
|
|
hrExpected = S_OK;
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), hrExpected);
|
|
if (hrExpected == S_OK) {
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
}
|
|
|
|
// try the same when creating a table
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), hrExpected);
|
|
if (hrExpected == S_OK)
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a primary key constraint. Drop it. Create a primary key using the same name as before.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CPrimaryKeyCons cons;
|
|
DBCONSTRAINTDESC *pConsDesc = (DBCONSTRAINTDESC*)cons;
|
|
CCol col;
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// build the constraint
|
|
|
|
// try to set all the columns as primary key
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
ReleaseDBID(&pConsDesc->rgColumnList[0], FALSE);
|
|
TESTC_(Table.GetColInfo(2, col), S_OK);
|
|
DuplicateDBID(*col.GetColID(), &pConsDesc->rgColumnList[0]);
|
|
|
|
// create constraint with the same name as before, different column
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create multiple-columned primary key
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CPrimaryKeyCons cons;
|
|
CCol col;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(Table.GetColInfo(2, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// try the same when creating a table
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create multiple primary key constraints using successive calls
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_5()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CPrimaryKeyCons cons;
|
|
CConsDescArray consArray;
|
|
CCol col;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// build the constraint
|
|
TESTC_(AddPrimaryKeyConstraint(&Table, 1), S_OK);
|
|
TESTC_(AddPrimaryKeyConstraint(&Table, 1), DB_E_DUPLICATECONSTRAINTID);
|
|
|
|
// try the same when creating a table
|
|
|
|
// add a first PK constraint
|
|
cons.AddColumn(&rgNewColumnDesc[0].dbcid);
|
|
cons.AddColumn(&rgNewColumnDesc[1].dbcid);
|
|
consArray.AddConsDesc(cons);
|
|
|
|
// add a second PK constraint
|
|
CHECK(cons.MakeConstraintName(), S_OK);
|
|
cons.ReleaseColumnList();
|
|
cons.AddColumn(&rgNewColumnDesc[2].dbcid);
|
|
consArray.AddConsDesc(cons);
|
|
|
|
if (!CHECK(hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, consArray, consArray, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_DUPLICATECONSTRAINTID) && SUCCEEDED(hr))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Successive calls, lists of columns overlap
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_6()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CPrimaryKeyCons cons;
|
|
CPrimaryKeyCons cons2;
|
|
CCol col;
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// build the constraint
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(Table.GetColInfo(2, col), S_OK);
|
|
cons2.AddColumn(col.GetColID());
|
|
|
|
// try create second constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons2), DB_E_DUPLICATECONSTRAINTID);
|
|
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons2), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a nullable column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_7()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CPrimaryKeyCons cons;
|
|
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// identify a nullable column
|
|
TESTC_PROVIDER(S_OK == Table.GetColInfo(IsCColNullable, col));
|
|
|
|
|
|
CHECK(AddPrimaryKeyConstraint(&Table, col.GetColNum()), E_FAIL);
|
|
|
|
// try the same when creating a table
|
|
cons.AddColumn(&rgNewColumnDesc[0].dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), E_FAIL);
|
|
//
|
|
//{
|
|
// CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
// ReleaseDBID(pTableID, TRUE);
|
|
//}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a not nullable column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_8()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CPrimaryKeyCons cons;
|
|
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// add a primary key on a not nullable column
|
|
CHECK(AddPrimaryKeyConstraint(&Table, 1), S_OK);
|
|
|
|
// try the same when creating a table
|
|
cons.AddColumn(&rgNewColumnDesc[0].dbcid);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a column with a default value
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_9()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
VARIANT value;
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
DBID *pTableID = NULL;
|
|
CPrimaryKeyCons cons;
|
|
|
|
Table.CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
VariantInit(&value);
|
|
odtLog << "Default value on type " << rgNewColumnDesc[0].pwszTypeName << "\n";
|
|
GetDefaultValue(&rgNewColumnDesc[0], &value, &Table);
|
|
SetDefaultProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
&value, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&value);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// add a PK on a column with a default value
|
|
CHECK(AddPrimaryKeyConstraint(&Table, 1), S_OK);
|
|
|
|
// try the same when creating a table
|
|
cons.AddColumn(&rgNewColumnDesc[0].dbcid);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a column defined as unique
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_10()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CPrimaryKeyCons cons;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_COL_UNIQUE, DBPROPSET_COLUMN, m_pIDBInitialize));
|
|
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_UNIQUE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_OPTIONAL);
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TEST2C_(Table.CreateTable(0, 0), S_OK, DB_S_ERRORSOCCURRED);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// add PK on a unique column
|
|
CHECK(AddPrimaryKeyConstraint(&Table, 1), S_OK);
|
|
|
|
// try the same when creating a table
|
|
CHECK(cons.MakeConstraintName(), S_OK);
|
|
cons.AddColumn(&rgNewColumnDesc[0].dbcid);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a column defined as primary key => DB_E_DUPLICATECONSTRAINTID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_11()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CPrimaryKeyCons cons;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_COL_PRIMARYKEY, DBPROPSET_COLUMN, m_pIDBInitialize));
|
|
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_PRIMARYKEY,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_OPTIONAL);
|
|
Table.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
|
|
TEST2C_(Table.CreateTable(0, 0), S_OK, DB_S_ERRORSOCCURRED);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// since there already is a primary key on this table
|
|
// expect DB_E_DUPLICATECONSTRAINTID
|
|
CHECK(AddPrimaryKeyConstraint(&Table, 1), DB_E_DUPLICATECONSTRAINTID);
|
|
|
|
// try the same when creating a table
|
|
cons.AddColumn(&rgNewColumnDesc[0].dbcid);
|
|
if (!CHECK(hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_DUPLICATECONSTRAINTID) && SUCCEEDED(hr))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a column that already has a primary key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col;
|
|
CPrimaryKeyCons cons;
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// identify a nullable column
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// alloc memory for column array
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// another constraint ID
|
|
CHECK(cons.MakeConstraintName(), S_OK);
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_DUPLICATECONSTRAINTID);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a column that is part of a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_13()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL indexCol = 1;
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
CPrimaryKeyCons cons;
|
|
CForeignKeyCons consFK;
|
|
CConsDescArray consArray;
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
// create a base table without nullable columns and a reference table
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(BaseTable.CountColumnsOnTable() == ReferencedTable.CountColumnsOnTable())
|
|
|
|
// prepare and add the unique constraint on the referenced table
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, indexCol), S_OK);
|
|
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, 1, &indexCol,
|
|
&ReferencedTable, 1, &indexCol, m_SupportedMatchType), S_OK);
|
|
|
|
// add the PK constraint on the BaseTable
|
|
CHECK(AddPrimaryKeyConstraint(&BaseTable, indexCol), S_OK);
|
|
|
|
// try the same on a table -> create a PK and a FK, their column lists are not disjoint
|
|
// add a first PK constraint
|
|
TESTC_(ReferencedTable.GetColInfo(indexCol, col), S_OK);
|
|
consFK.AddColumn(col.GetColID());
|
|
consFK.AddForeignKeyColumn(&rgNewColumnDesc[indexCol-1].dbcid);
|
|
consFK.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
consArray.AddConsDesc(consFK);
|
|
|
|
// add a second PK constraint
|
|
cons.AddColumn(&rgNewColumnDesc[indexCol-1].dbcid);
|
|
consArray.AddConsDesc(cons);
|
|
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, consArray, consArray, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a column that is part of an index
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_14()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL ulIndexCol = 1;
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0, ulIndexCol), S_OK);
|
|
|
|
// add a PK constraint on the index column
|
|
TESTC_(AddPrimaryKeyConstraint(&Table, ulIndexCol), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a column on a not empty table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_15()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 10), S_OK);
|
|
|
|
// add PK constraint
|
|
TESTC_(AddPrimaryKeyConstraint(&Table, 1), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint on a column that already has duplicates (for the whole key)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_16()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
|
|
// create a base table without nullable columns
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 10), S_OK);
|
|
TESTC_(Table.Insert(7), S_OK);
|
|
|
|
// expect DB_E_SCHEMAVIOLATION because the table already contains duplicates
|
|
TESTC_(AddPrimaryKeyConstraint(&Table, 1), DB_E_SCHEMAVIOLATION);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Primary key constraint that has duplicates for a column in the key, but not for the whole key
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_17()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CPrimaryKeyCons cons;
|
|
CCol col;
|
|
VARIANT value;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
HRESULT hr;
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
|
|
Table.CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
// create a new table with a NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
SetProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
VariantInit(&value);
|
|
GetDefaultValue(&rgNewColumnDesc[0], &value, &Table);
|
|
SetDefaultProperty(&rgNewColumnDesc[0].rgPropertySets, &rgNewColumnDesc[0].cPropertySets,
|
|
&value, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&value);
|
|
Table.SetColumnDesc(rgNewColumnDesc+1, m_cColumnDesc-1);
|
|
Table.SetBuildColumnDesc(FALSE);
|
|
SetProperty(&rgNewColumnDesc[1].rgPropertySets, &rgNewColumnDesc[1].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
TEST2C_(hr = Table.CreateTable(10, 0), S_OK, DB_S_ERRORSOCCURRED);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
TEST2C_(hr = m_pITableDefinition->AddColumn(&Table.GetTableID(),
|
|
rgNewColumnDesc, NULL), S_OK, DB_E_ERRORSOCCURRED);
|
|
TESTC(S_OK == hr);
|
|
|
|
// identify a nullable column
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// build the primary key
|
|
cons.AddColumn(&rgNewColumnDesc[0].dbcid);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.SetColumnDesc(NULL, 0);
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_18()
|
|
{
|
|
CAddPrimaryKeyConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort non retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_19()
|
|
{
|
|
CAddPrimaryKeyConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_20()
|
|
{
|
|
CAddPrimaryKeyConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit non retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_21()
|
|
{
|
|
CAddPrimaryKeyConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create PK in a different catalog
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_PRIMARYKEY::Variation_22()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CPrimaryKeyCons cons;
|
|
DBCONSTRAINTDESC *pConsDesc = (DBCONSTRAINTDESC*)cons;
|
|
CCol col;
|
|
DBORDINAL indxCat = 0;
|
|
CCatalogs Catalogs(m_pIOpenRowset);
|
|
IDBProperties *pIDBProperties = NULL;
|
|
CPropSets PropSets;
|
|
WCHAR *pwszCurrentCatalog = NULL;
|
|
WCHAR *pwszQualTableName = NULL;
|
|
WCHAR *pwszCatalogName = NULL;
|
|
WCHAR *pwszSchemaName = NULL;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, m_pIDBInitialize));
|
|
TESTC_PROVIDER(1 < Catalogs.cCatalogs());
|
|
|
|
// create a table and an index
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// select column
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// set DBID of the table to its qualified form
|
|
TESTC(DBKIND_NAME == Table.GetTableID().eKind);
|
|
|
|
TESTC(GetCatalogSchemaNames(Table.GetTableName(), &pwszCatalogName, &pwszSchemaName));
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(m_pTable->GetQualifiedName(pwszCatalogName, pwszSchemaName, Table.GetTableName(), &pwszQualTableName),S_OK);
|
|
Table.SetTableName(pwszQualTableName);
|
|
|
|
// change the current catalog
|
|
TESTC(GetProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, m_pIDBInitialize,
|
|
&pwszCurrentCatalog));
|
|
TESTC(NULL != pwszCurrentCatalog);
|
|
|
|
TESTC(VerifyInterface(m_pIDBInitialize, IID_IDBProperties, DATASOURCE_INTERFACE, (IUnknown**)&pIDBProperties));
|
|
|
|
if (0 == wcscmp(pwszCurrentCatalog, Catalogs[0]))
|
|
indxCat++;
|
|
|
|
CHECK(PropSets.AddProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, VT_BSTR, (LPVOID)Catalogs[indxCat]), S_OK);
|
|
TESTC_PROVIDER(S_OK == pIDBProperties->SetProperties(PropSets, PropSets));
|
|
|
|
// alloc memory for column array
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
// try to make column unique
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
if (CHECK(PropSets.SetProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, VT_BSTR, (LPVOID)pwszCurrentCatalog), S_OK))
|
|
CHECK(pIDBProperties->SetProperties(PropSets, PropSets), S_OK);
|
|
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
SAFE_FREE(pwszQualTableName);
|
|
SAFE_FREE(pwszCurrentCatalog);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
int TCAddConstraint_PRIMARYKEY::Variation_23() {
|
|
TBEGIN
|
|
|
|
CLimitTable Table;
|
|
|
|
TESTC_(Table.CheckPrimaryKeyLimit(), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAddConstraint_PRIMARYKEY::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAddConstraint_FOREIGNKEY)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAddConstraint_FOREIGNKEY - Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_FOREIGNKEY
|
|
//| Created: 7/29/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddConstraint_FOREIGNKEY::Init()
|
|
{
|
|
m_pReferenceTable = NULL;
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC==NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
m_pReferenceTable = new CTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
TESTC_(m_pReferenceTable->CreateTable(0, 1), S_OK);
|
|
m_pReferenceTable->AddInfoFromColumnsSchemaRowset(m_pITDWC, m_pReferenceTable->GetTableName());
|
|
return TRUE;
|
|
}
|
|
CLEANUP:
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Simple foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_1()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col, col2;
|
|
DBORDINAL indexCol = 1;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
|
|
// select columns from tables
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
Table.BuildColumnDescs(&rgNewColumnDesc);
|
|
|
|
TESTC(Table.CountColumnsOnTable() == m_pReferenceTable->CountColumnsOnTable())
|
|
TESTC_(Table.GetColInfo(indexCol, col), S_OK);
|
|
TESTC_(m_pReferenceTable->GetColInfo(indexCol, col2), S_OK);
|
|
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
cons.AddColumn(col2.GetColID());
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
cons.SetReferencedTableID(&m_pReferenceTable->GetTableID());
|
|
|
|
// add the foreign key constraint
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// try the same when creating a table
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Foregin key is made of several columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_2()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1, 2};
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CCol col;
|
|
DBORDINAL index;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(BaseTable.CountColumnsOnTable() == RefTable.CountColumnsOnTable())
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// add the foreign key constraint
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// try the same when creating a table
|
|
for (index=0; index < NUMELEM(rgCol); index++)
|
|
{
|
|
TESTC_(RefTable.GetColInfo(rgCol[index], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol[index]-1].dbcid);
|
|
}
|
|
cons.SetReferencedTableID(&RefTable.GetTableID());
|
|
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multiple foreign key constraints on a table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1, 2};
|
|
DBORDINAL rgCol2[] = {3, 4};
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
CConsDescArray consArray;
|
|
CCol col;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(BaseTable.CountColumnsOnTable() == RefTable.CountColumnsOnTable())
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol2), rgCol2), S_OK);
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set a second foreign constraint
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol2), rgCol2,
|
|
&RefTable, NUMELEM(rgCol2), rgCol2, m_SupportedMatchType), S_OK);
|
|
|
|
// try to create a table with 2 disjoint FK constraint
|
|
TESTC_(RefTable.GetColInfo(rgCol[0], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(RefTable.GetColInfo(rgCol[1], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol[0]-1].dbcid);
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol[1]-1].dbcid);
|
|
cons.SetReferencedTableID(&RefTable.GetTableID());
|
|
consArray.AddConsDesc(cons);
|
|
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
CHECK(cons.ReleaseColumnList(), S_OK);
|
|
CHECK(cons.ReleaseForeignKeyColumnList(), S_OK);
|
|
TESTC_(RefTable.GetColInfo(rgCol2[0], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(RefTable.GetColInfo(rgCol2[1], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol2[0]-1].dbcid);
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol2[1]-1].dbcid);
|
|
consArray.AddConsDesc(cons);
|
|
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, consArray, consArray, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multiple overlapping foreign key constraints
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1, 2};
|
|
DBORDINAL rgCol2[] = {3, 2};
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
CConsDescArray consArray;
|
|
CCol col;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(BaseTable.CountColumnsOnTable() == RefTable.CountColumnsOnTable())
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol2), rgCol2), S_OK);
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// set a second foreign constraint
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol2), rgCol2,
|
|
&RefTable, NUMELEM(rgCol2), rgCol2, m_SupportedMatchType), S_OK);
|
|
|
|
// try to create a table with 2 overlapping FK constraint
|
|
TESTC_(RefTable.GetColInfo(rgCol[0], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(RefTable.GetColInfo(rgCol[1], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol[0]-1].dbcid);
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol[1]-1].dbcid);
|
|
cons.SetReferencedTableID(&RefTable.GetTableID());
|
|
consArray.AddConsDesc(cons);
|
|
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
CHECK(cons.ReleaseColumnList(), S_OK);
|
|
CHECK(cons.ReleaseForeignKeyColumnList(), S_OK);
|
|
TESTC_(RefTable.GetColInfo(rgCol2[0], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(RefTable.GetColInfo(rgCol2[1], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol2[0]-1].dbcid);
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol2[1]-1].dbcid);
|
|
consArray.AddConsDesc(cons);
|
|
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, consArray, consArray, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a foreign key on each column of the table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_5()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
DBORDINAL indexCol;
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
BaseTable.BuildColumnDescs(&rgNewColumnDesc);
|
|
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(BaseTable.CountColumnsOnTable() == RefTable.CountColumnsOnTable())
|
|
|
|
// set referenced table
|
|
cons.SetReferencedTableID(&RefTable.GetTableID());
|
|
|
|
// make room for columns id
|
|
for (indexCol = 1; indexCol <= BaseTable.CountColumnsOnTable(); indexCol++)
|
|
{
|
|
if (!CHECK(BaseTable.GetColInfo(indexCol, col), S_OK))
|
|
continue;
|
|
|
|
odtLog << col.GetProviderTypeName() << "\n";
|
|
|
|
// make the referenced columns unique
|
|
if (S_OK != AddUniqueConstraint(&RefTable, indexCol))
|
|
continue;
|
|
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
// set column on base table
|
|
cons.ReleaseForeignKeyColumnList();
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
|
|
// set foreign column
|
|
if (!CHECK(RefTable.GetColInfo(indexCol, col), S_OK))
|
|
continue;
|
|
cons.ReleaseColumnList();
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
// add the foreign key constraint
|
|
if (CHECK(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK))
|
|
{
|
|
// drop the constraint
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
}
|
|
|
|
// try the same when creating a table
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a foreign key on all columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_6()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
DBORDINAL indexCol;
|
|
CUniqueCons consUnique;
|
|
ULONG_PTR uMaxColsInIndex = 0,
|
|
uAdded = 0,
|
|
uMaxIndexSize = 0,
|
|
uCurIndexSize = 0,
|
|
uColSizeInBytes = 0;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(BaseTable.CountColumnsOnTable() == RefTable.CountColumnsOnTable())
|
|
|
|
// set referenced table
|
|
cons.SetReferencedTableID(&RefTable.GetTableID());
|
|
|
|
if (SupportedProperty(DBPROP_MAXINDEXSIZE, DBPROPSET_DATASOURCEINFO, GetModInfo()->GetThisTestModule()->m_pIUnknown, DATASOURCE_INTERFACE))
|
|
TESTC(GetProperty(DBPROP_MAXINDEXSIZE, DBPROPSET_DATASOURCEINFO, GetModInfo()->GetThisTestModule()->m_pIUnknown, &uMaxIndexSize));
|
|
|
|
for (indexCol = 1; indexCol <= BaseTable.CountColumnsOnTable(); indexCol++)
|
|
{
|
|
// set column on base table
|
|
TESTC_(BaseTable.GetColInfo(indexCol, col), S_OK);
|
|
|
|
// Note: col.GetColumnSize returns length for string data types and we need size in bytes
|
|
// so multiply ColumnSize by 2 for WSTR
|
|
if(col.GetIsFixedLength() )
|
|
uColSizeInBytes = col.GetColumnSize() * (col.GetProviderType()==DBTYPE_WSTR ? 2:1);
|
|
else
|
|
uColSizeInBytes = 0;
|
|
|
|
|
|
if (uMaxIndexSize && (uMaxIndexSize - uCurIndexSize) < uColSizeInBytes)
|
|
continue;
|
|
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
|
|
// set foreign column
|
|
TESTC_(RefTable.GetColInfo(indexCol, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
consUnique.AddColumn(col.GetColID());
|
|
|
|
uAdded++;
|
|
uCurIndexSize += uColSizeInBytes;
|
|
|
|
if (uMaxColsInIndex && uAdded == uMaxColsInIndex)
|
|
break;
|
|
}
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &RefTable.GetTableID(), consUnique), S_OK);
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create foreign key and try to drop the reference table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_7()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
CCol col;
|
|
DBORDINAL rgCol[] = {1};
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(BaseTable.CountColumnsOnTable() == RefTable.CountColumnsOnTable())
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// try to drop the table or a column in the FK constraint
|
|
TESTC_PROVIDER(S_OK == RefTable.GetColInfo(rgCol[0], col));
|
|
CHECK(DropTableAndCheck(&RefTable.GetTableID()), DB_E_DROPRESTRICTED);
|
|
CHECK(DropColumnAndCheck(&RefTable.GetTableID(), col.GetColID()), DB_E_DROPRESTRICTED);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc On a nullable column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_8()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL rgCol[] = {1};
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
CForeignKeyCons cons;
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
SetProperty(&rgNewColumnDesc[rgCol[0]-1].rgPropertySets, &rgNewColumnDesc[rgCol[0]-1].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
BaseTable.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
BaseTable.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// add the FK constraint on the NULLABLE column
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// try the same when creating a table
|
|
cons.SetReferencedTableID(&RefTable.GetTableID());
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol[0]-1].dbcid);
|
|
TESTC_(RefTable.GetColInfo(rgCol[0], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc On a not nullable column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL rgCol[] = {1};
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
CForeignKeyCons cons;
|
|
CCol col;
|
|
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
SetProperty(&rgNewColumnDesc[rgCol[0]-1].rgPropertySets, &rgNewColumnDesc[rgCol[0]-1].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
BaseTable.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
BaseTable.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// add the FK constraint on the not NULLABLE column
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// try the same when creating a table
|
|
cons.SetReferencedTableID(&RefTable.GetTableID());
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol[0]-1].dbcid);
|
|
TESTC_(RefTable.GetColInfo(rgCol[0], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc On a column having a default value
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_10()
|
|
{
|
|
TBEGIN
|
|
VARIANT value;
|
|
DBORDINAL rgCol[] = {1};
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
DBID *pTableID = NULL;
|
|
CForeignKeyCons cons;
|
|
CCol col;
|
|
|
|
BaseTable.CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
VariantInit(&value);
|
|
GetDefaultValue(&rgNewColumnDesc[rgCol[0]-1], &value, &BaseTable);
|
|
SetDefaultProperty(&rgNewColumnDesc[rgCol[0]-1].rgPropertySets, &rgNewColumnDesc[rgCol[0]-1].cPropertySets,
|
|
&value, DBPROPOPTIONS_REQUIRED); // might be not supported
|
|
VariantClear(&value);
|
|
BaseTable.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
BaseTable.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// add the FK constraint
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// try the same when creating a table
|
|
cons.SetReferencedTableID(&RefTable.GetTableID());
|
|
cons.AddForeignKeyColumn(&rgNewColumnDesc[rgCol[0]-1].dbcid);
|
|
TESTC_(RefTable.GetColInfo(rgCol[0], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, 1, cons, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc On a column defined as unique
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_11()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons cons;
|
|
CCol col, col2;
|
|
CConsDescArray consArray;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
BaseTable.BuildColumnDescs(&rgNewColumnDesc);
|
|
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// select a column
|
|
TESTC(BaseTable.CountColumnsOnTable() == RefTable.CountColumnsOnTable())
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// make the base column unique
|
|
TESTC_(AddUniqueConstraint(&BaseTable, NUMELEM(rgCol), rgCol), S_OK);
|
|
|
|
// add the FK constraint
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// try to create a table with a unique and a FK cons
|
|
TESTC_(RefTable.GetColInfo(rgCol[0], col), S_OK);
|
|
TESTC_(BaseTable.GetColInfo(rgCol[0], col2), S_OK);
|
|
cons.AddColumn(col2.GetColID());
|
|
consArray.AddConsDesc(cons);
|
|
|
|
consFK.SetReferencedTableID(&RefTable.GetTableID());
|
|
consFK.AddForeignKeyColumn(col2.GetColID());
|
|
consFK.AddColumn(col.GetColID());
|
|
consArray.AddConsDesc(consFK);
|
|
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, consArray, consArray, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc On a primary key column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBID *pTableID = NULL;
|
|
CForeignKeyCons consFK;
|
|
CPrimaryKeyCons cons;
|
|
CCol col, col2;
|
|
CConsDescArray consArray;
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
BaseTable.BuildColumnDescs(&rgNewColumnDesc);
|
|
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, rgCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// make the base column unique
|
|
TESTC_(AddPrimaryKeyConstraint(&BaseTable, rgCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// add FK constraint
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
// try to create a table with a unique and a FK cons
|
|
TESTC_(RefTable.GetColInfo(rgCol[0], col), S_OK);
|
|
TESTC_(BaseTable.GetColInfo(rgCol[0], col2), S_OK);
|
|
cons.AddColumn(col2.GetColID());
|
|
consArray.AddConsDesc(cons);
|
|
|
|
consFK.SetReferencedTableID(&RefTable.GetTableID());
|
|
consFK.AddForeignKeyColumn(col2.GetColID());
|
|
consFK.AddColumn(col.GetColID());
|
|
consArray.AddConsDesc(consFK);
|
|
|
|
TESTC_(cons.MakeConstraintName(), S_OK);
|
|
if (CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
m_cColumnDesc, rgNewColumnDesc, consArray, consArray, IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK))
|
|
{
|
|
CHECK(DropTableAndCheck(pTableID, m_pITDWC), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgNewColumnDesc, m_cColumnDesc, TRUE);
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc On a column that is part of the index
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_13()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 1), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 1), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc On a table that is in another catalog
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_14()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCatalogs Catalogs(m_pIOpenRowset);
|
|
WCHAR *pwszCurrentCatalog = NULL;
|
|
WCHAR *pwszCatalogName = NULL;
|
|
WCHAR *pwszSchemaName = NULL;
|
|
WCHAR *pwszQualTableName = NULL;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, m_pIDBInitialize));
|
|
TESTC_PROVIDER(1 < Catalogs.cCatalogs());
|
|
|
|
// store the name of the current catalog
|
|
TESTC(Catalogs.GetCurrentCatalog(&pwszCurrentCatalog));
|
|
|
|
// change the current catalog
|
|
TESTC_(Catalogs.ChangeCurrentCatalog(), S_OK);
|
|
|
|
// create the referenced table in this catalog
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.CreateTable(0, 0));
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
TESTC(GetCatalogSchemaNames(ReferencedTable.GetTableName(), &pwszCatalogName, &pwszSchemaName));
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(BaseTable.GetQualifiedName(pwszCatalogName, pwszSchemaName, ReferencedTable.GetTableName(), &pwszQualTableName),S_OK);
|
|
ReferencedTable.SetTableName(pwszQualTableName);
|
|
|
|
// switch back the current catalog
|
|
TESTC_(Catalogs.SetCurrentCatalog(pwszCurrentCatalog), S_OK);
|
|
|
|
// create the base table
|
|
BaseTable.SetTableName(NULL);
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// create the
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType), S_OK);
|
|
|
|
CLEANUP:
|
|
if (pwszCurrentCatalog)
|
|
// restore the name of the current catalog
|
|
COMPARE(Catalogs.SetCurrentCatalog(pwszCurrentCatalog), S_OK);
|
|
|
|
SAFE_FREE(pwszCurrentCatalog);
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
SAFE_FREE(pwszQualTableName);
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use different combination for update/delete rules, as well as match type
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_15()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
|
|
DBUPDELRULE rgUPDLValues[] = {DBUPDELRULE_NOACTION, DBUPDELRULE_CASCADE,
|
|
DBUPDELRULE_SETNULL, DBUPDELRULE_SETDEFAULT};
|
|
WCHAR *rgUPDLValuesText[] = {L"DBUPDELRULE_NOACTION", L"DBUPDELRULE_CASCADE",
|
|
L"DBUPDELRULE_SETNULL", L"DBUPDELRULE_SETDEFAULT"};
|
|
DBORDINAL indexDelete;
|
|
DBORDINAL indexUpdate;
|
|
|
|
DBMATCHTYPE rgMatchType[] = {DBMATCHTYPE_NONE, DBMATCHTYPE_FULL, DBMATCHTYPE_PARTIAL};
|
|
WCHAR *rgMatchTypeText[] = {L"DBMATCHTYPE_NONE", L"DBMATCHTYPE_FULL", L"DBMATCHTYPE_PARTIAL"};
|
|
DBORDINAL indexMatchType;
|
|
|
|
DBORDINAL cSuccess = 0;
|
|
HRESULT hr;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 1), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
for (indexDelete = 0; indexDelete < NUMELEM(rgUPDLValues); indexDelete++)
|
|
{
|
|
// all delete rules
|
|
odtLog << "\t" << rgUPDLValuesText[indexDelete] << "\n";
|
|
for (indexUpdate = 0; indexUpdate < NUMELEM(rgUPDLValues); indexUpdate++)
|
|
{
|
|
// all update rules
|
|
odtLog << "\t\t" << rgUPDLValuesText[indexUpdate] << "\n";
|
|
for (indexMatchType = 0; indexMatchType < NUMELEM(rgMatchType); indexMatchType++)
|
|
{
|
|
CForeignKeyCons cons;
|
|
|
|
// all match type rules
|
|
odtLog << "\t\t\t" << rgMatchTypeText[indexMatchType];
|
|
|
|
cons.SetConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol,
|
|
rgMatchType[indexMatchType],
|
|
rgUPDLValues[indexUpdate],
|
|
rgUPDLValues[indexDelete],
|
|
(DBDEFERRABILITY)0);
|
|
|
|
hr = AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
odtLog << "\n";
|
|
cSuccess++;
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(),
|
|
cons.GetConstraintID()), S_OK);
|
|
}
|
|
else if (DB_E_BADUPDATEDELETERULE != hr && DB_E_BADMATCHTYPE!= hr)
|
|
{
|
|
CHECK(hr, S_OK);
|
|
}
|
|
else
|
|
odtLog << "\tunsupported " << ((DB_E_BADUPDATEDELETERULE == hr) ? "rule" : "match type") << "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
TESTC(0 < cSuccess);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Referenced table name and base table names have maximum length
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_16()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
WCHAR *pwszTableName = NULL;
|
|
|
|
BaseTable.MakeTableName(NULL);
|
|
pwszTableName = BuildValidName(m_cMaxTableName, BaseTable.GetTableName());
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0, pwszTableName), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszTableName);
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Columns in the foreign key (base table and reference table) have different names
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_17()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBCOLUMNDESC *rgNewColumnDesc = NULL;
|
|
DBORDINAL rgCol[] = {1};
|
|
|
|
// the name of the column should be different
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgNewColumnDesc);
|
|
ReleaseDBID(&rgNewColumnDesc[0].dbcid, FALSE);
|
|
rgNewColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgNewColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"AnotherColumn");
|
|
BaseTable.SetColumnDesc(rgNewColumnDesc, m_cColumnDesc);
|
|
BaseTable.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol), rgCol, m_SupportedMatchType), S_OK);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Different size in column lists (base table and referenced)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_18()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable RefTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCol[] = {1};
|
|
DBORDINAL rgCol2[] = {1, 2};
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(RefTable.CreateTable(0, 0), S_OK);
|
|
RefTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&RefTable, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol2), rgCol2, m_SupportedMatchType), E_INVALIDARG);
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgCol), rgCol,
|
|
&RefTable, NUMELEM(rgCol2), rgCol2, m_SupportedMatchType), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
RefTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Column types in base table and reference table are different
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_19()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {3};
|
|
CCol col;
|
|
HRESULT hr;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// find 2 columns of different types (DBTYPE_I4 and DBTYPE_R4)
|
|
TESTC_PROVIDER(S_OK == ReferencedTable.GetColInfo(col, DBTYPE_I4));
|
|
rgReferencedCol[0] = col.GetColNum();
|
|
TESTC_PROVIDER(S_OK == BaseTable.GetColInfo(col, DBTYPE_R4));
|
|
rgBaseCol[0] = col.GetColNum();
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
CHECK(ReferencedTable.GetColInfo(rgReferencedCol[0], col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
CHECK(BaseTable.GetColInfo(rgBaseCol[0], col), S_OK);
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
cons.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
CHECK(hr = AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons, TRUE), DB_E_BADCONSTRAINTFORM);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// challenge the constraint
|
|
TESTC_(ReferencedTable.Insert(12), S_OK);
|
|
TESTC_(BaseTable.Insert(12), S_OK);
|
|
}
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid value for the update rule
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_20()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType, 0xFF), DB_E_BADUPDATEDELETERULE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid value for the delete rule
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_21()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType, DBUPDELRULE_NOACTION, 0xFF), DB_E_BADUPDATEDELETERULE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid value for the MatchType
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_22()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
CHECK(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
0xFF), DB_E_BADMATCHTYPE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent column names in the referenced table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_23()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons cons;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(cons.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol, m_SupportedMatchType), S_OK);
|
|
|
|
// release the referenced column and set inexistent name
|
|
SAFE_FREE(((DBCONSTRAINTDESC*)cons)->rgColumnList[0].uName.pwszName);
|
|
((DBCONSTRAINTDESC*)cons)->rgColumnList[0].uName.pwszName = wcsDuplicate(L"NuExista");
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent column name in the base table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_24()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons cons;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(cons.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol, m_SupportedMatchType), S_OK);
|
|
|
|
// release the referenced column and set inexistent name
|
|
SAFE_FREE(((DBCONSTRAINTDESC*)cons)->rgForeignKeyColumnList[0].uName.pwszName);
|
|
((DBCONSTRAINTDESC*)cons)->rgForeignKeyColumnList[0].uName.pwszName = wcsDuplicate(L"NuExista");
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent base table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_25()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons cons;
|
|
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(cons.SetConstraint(&ReferencedTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol, m_SupportedMatchType), S_OK);
|
|
|
|
TESTC_(BaseTable.MakeTableName(NULL), S_OK);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent reference table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_26()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons cons;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// since base table name has to be inexistent, use reference table name instead
|
|
TESTC_(cons.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&BaseTable, NUMELEM(rgReferencedCol), rgReferencedCol, m_SupportedMatchType), S_OK);
|
|
|
|
// fill-in an inexistent table name
|
|
TESTC_(ReferencedTable.MakeTableName(NULL), S_OK);
|
|
ReleaseDBID(((DBCONSTRAINTDESC*)cons)->pReferencedTableID, FALSE);
|
|
TESTC_(DuplicateDBID(ReferencedTable.GetTableID(), ((DBCONSTRAINTDESC*)cons)->pReferencedTableID), S_OK);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL pConstraintID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_27()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CForeignKeyCons cons;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
TESTC_(cons.SetConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol, m_SupportedMatchType), S_OK);
|
|
|
|
// release pConstraintID
|
|
ReleaseDBID(((DBCONSTRAINTDESC*)cons)->pConstraintID, TRUE);
|
|
((DBCONSTRAINTDESC*)cons)->pConstraintID = NULL;
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Referenced col list is not a unique / pk constraint => failure
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_28()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col, col2;
|
|
DBORDINAL indexCol = 1;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// select columns from tables
|
|
TESTC(BaseTable.CountColumnsOnTable() == ReferencedTable.CountColumnsOnTable())
|
|
TESTC_(BaseTable.GetColInfo(indexCol, col), S_OK);
|
|
TESTC_(ReferencedTable.GetColInfo(indexCol, col2), S_OK);
|
|
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
cons.AddColumn(col2.GetColID());
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
cons.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), E_FAIL);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a foreign key and then insert a NULL value for one of the fk columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_29()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgCols[] = {1, 2, 3};
|
|
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
|
|
DBMATCHTYPE rgMatchType[] = {DBMATCHTYPE_NONE, DBMATCHTYPE_FULL, DBMATCHTYPE_PARTIAL};
|
|
WCHAR *rgMatchTypeText[] = {L"DBMATCHTYPE_NONE", L"DBMATCHTYPE_FULL", L"DBMATCHTYPE_PARTIAL"};
|
|
DBORDINAL indexMatchType;
|
|
|
|
DBORDINAL cSuccess = 0;
|
|
HRESULT hr;
|
|
|
|
const DBORDINAL cProp = 1;
|
|
DBPROP rgProp[cProp];
|
|
|
|
const DBORDINAL cPropSets = 1;
|
|
DBPROPSET rgPropSets[cPropSets];
|
|
|
|
rgPropSets[0].guidPropertySet = DBPROPSET_ROWSET;
|
|
rgPropSets[0].cProperties = 1;
|
|
rgPropSets[0].rgProperties = rgProp;
|
|
|
|
memset(rgProp, 0, sizeof(DBPROP));
|
|
rgProp[0].dwPropertyID = DBPROP_UPDATABILITY;
|
|
rgProp[0].vValue.vt = VT_I4;
|
|
V_I4(&rgProp[0].vValue) = DBPROPVAL_UP_INSERT;
|
|
|
|
CList<WCHAR *,WCHAR *> NativeTypesList;
|
|
CList<DBTYPE,DBTYPE> ProviderTypesList;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
|
|
BaseTable.CreateTypeColInfo(NativeTypesList, ProviderTypesList);
|
|
TESTC_PROVIDER(2 < m_cColumnDesc);
|
|
// create a new table with a NOT NULLABLE column
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
SetProperty(&rgColumnDesc[1].rgPropertySets, &rgColumnDesc[1].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
SetProperty(&rgColumnDesc[2].rgPropertySets, &rgColumnDesc[2].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
BaseTable.SetColumnDesc(rgColumnDesc, m_cColumnDesc);
|
|
BaseTable.SetBuildColumnDesc(FALSE);
|
|
|
|
TESTC_PROVIDER(S_OK == BaseTable.CreateTable(0, 0));
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(CreateTableWithNoNullableColumns(&ReferencedTable, 5, 0), S_OK);
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, NUMELEM(rgCols), rgCols, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
for (indexMatchType = 0; indexMatchType < NUMELEM(rgMatchType); indexMatchType++)
|
|
{
|
|
CForeignKeyCons cons;
|
|
|
|
// all match type rules
|
|
odtLog << "\t\t\t" << rgMatchTypeText[indexMatchType];
|
|
|
|
cons.SetConstraint(&BaseTable, NUMELEM(rgCols), rgCols,
|
|
&ReferencedTable, NUMELEM(rgCols), rgCols,
|
|
rgMatchType[indexMatchType],
|
|
DBUPDELRULE_NOACTION,
|
|
DBUPDELRULE_NOACTION,
|
|
(DBDEFERRABILITY)0);
|
|
|
|
hr = AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
odtLog << "\n";
|
|
cSuccess++;
|
|
{
|
|
// open a rowset on the base table
|
|
TESTC_(g_pIOpenRowset->OpenRowset(NULL, &BaseTable.GetTableID(), NULL,
|
|
IID_IRowsetChange, cPropSets, rgPropSets, (IUnknown**)&pIRowsetChange), S_OK);
|
|
|
|
// try to insert a NULL in the second column
|
|
// this should succeed if the match type is partial and the rest
|
|
// of the key matches a rows in the referenced table
|
|
CHECK(Insert(3, pIRowsetChange, 1, rgCols + 1, &BaseTable),
|
|
(DBMATCHTYPE_FULL != rgMatchType[indexMatchType])? S_OK: DB_E_INTEGRITYVIOLATION);
|
|
CHECK(Insert(3, pIRowsetChange, 3, rgCols, &BaseTable), S_OK);
|
|
//(DBMATCHTYPE_FULL == rgMatchType[indexMatchType])? S_OK: DB_E_INTEGRITYVIOLATION);
|
|
CHECK(Insert(32, pIRowsetChange, 1, rgCols + 1, &BaseTable),
|
|
(DBMATCHTYPE_NONE == rgMatchType[indexMatchType])? S_OK: DB_E_INTEGRITYVIOLATION);
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
}
|
|
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(),
|
|
cons.GetConstraintID()), S_OK);
|
|
}
|
|
else if (DB_E_BADMATCHTYPE!= hr)
|
|
{
|
|
CHECK(hr, S_OK);
|
|
}
|
|
else
|
|
odtLog << "\tunsupported " << ((DB_E_BADUPDATEDELETERULE == hr) ? "rule" : "match type") << "\n";
|
|
}
|
|
|
|
TESTC(0 < cSuccess);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc The referenced table and the base table are the same
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_30()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col, col2;
|
|
DBORDINAL indexCol = 1;
|
|
HRESULT hr;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, 1, &rgColumnDesc);
|
|
ReleaseDBID(&rgColumnDesc[0].dbcid, FALSE);
|
|
rgColumnDesc[0].dbcid.eKind = DBKIND_NAME;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = wcsDuplicate(L"NewColumn");
|
|
|
|
ReleaseAllColumnPropSets(rgColumnDesc, 1);
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
TESTC_(AddUniqueConstraint(&Table, indexCol), S_OK);
|
|
|
|
TESTC_(AddColumnAndCheck(&Table.GetTableID(), rgColumnDesc, NULL, m_pITDWC), S_OK);
|
|
|
|
// select columns from tables
|
|
TESTC_(Table.GetColInfo(indexCol, col), S_OK);
|
|
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
cons.AddColumn(col.GetColID());
|
|
cons.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
cons.SetReferencedTableID(&Table.GetTableID());
|
|
|
|
// add the foreign key constraint
|
|
hr = AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons);
|
|
|
|
TEST2C_(hr, S_OK, DB_E_BADMATCHTYPE);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, 1);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc The base and referenced tables are temporary tables
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_31()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
DBORDINAL indexCol = 1;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
CUniqueCons UniqueCons;
|
|
|
|
DBID *pBaseTableID = NULL;
|
|
DBID *pReferencedTableID = NULL;
|
|
DBPROPSET rgPropSets[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE));
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// temp table, TableID generated by provider
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProp), rgProp, DBPROPSET_TABLE);
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITDWC, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowset, NUMELEM(rgPropSets), rgPropSets, &pReferencedTableID, NULL), S_OK);
|
|
|
|
UniqueCons.AddColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, pReferencedTableID, UniqueCons), S_OK);
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITDWC, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowset, NUMELEM(rgPropSets), rgPropSets, &pBaseTableID, NULL), S_OK);
|
|
|
|
// select columns from tables
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
cons.AddColumn(&rgColumnDesc[0].dbcid);
|
|
cons.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
cons.SetReferencedTableID(pReferencedTableID);
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, pBaseTableID, cons), S_OK);
|
|
|
|
CLEANUP:
|
|
DropTableAndCheck(pBaseTableID);
|
|
DropTableAndCheck(pReferencedTableID);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pReferencedTableID, TRUE);
|
|
ReleaseDBID(pBaseTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Base table is a temporary table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_32()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col;
|
|
DBORDINAL indexCol = 1;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
|
|
DBID *pBaseTableID = NULL;
|
|
DBPROPSET rgPropSets[1];
|
|
DBPROP rgProp[1];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE));
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
|
|
// temp table, TableID generated by provider
|
|
FILL_PROP_SET(rgPropSets[0], NUMELEM(rgProp), rgProp, DBPROPSET_TABLE);
|
|
FILL_PROP(rgProp[0], DBPROP_TBL_TEMPTABLE, VT_BOOL, V_BOOL, VARIANT_TRUE, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(CreateAndCheckTable(m_pITDWC, NULL, NULL, cColumnDesc, rgColumnDesc,
|
|
IID_IRowset, NUMELEM(rgPropSets), rgPropSets, &pBaseTableID, NULL), S_OK);
|
|
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, indexCol), S_OK);
|
|
|
|
// select columns from tables
|
|
TESTC(ReferencedTable.CountColumnsOnTable() == cColumnDesc)
|
|
TESTC_(ReferencedTable.GetColInfo(indexCol, col), S_OK);
|
|
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
cons.AddColumn(col.GetColID());
|
|
cons.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
cons.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, pBaseTableID, cons), S_OK);
|
|
|
|
CLEANUP:
|
|
DropTableAndCheck(pBaseTableID);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pBaseTableID, TRUE);
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_33()
|
|
{
|
|
CAddFKConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort non retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_34()
|
|
{
|
|
CAddFKConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_35()
|
|
{
|
|
CAddFKConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit non retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_36()
|
|
{
|
|
CAddFKConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc The base table is already populated and the referenced one is empty => DB_E_SCHEMAVIOLATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_FOREIGNKEY::Variation_37()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCol col, col2;
|
|
DBORDINAL indexCol = 1;
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
|
|
TESTC_(BaseTable.CreateTable(5, 0), S_OK);
|
|
|
|
// select columns from tables
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC(BaseTable.CountColumnsOnTable() == m_pReferenceTable->CountColumnsOnTable())
|
|
TESTC_(BaseTable.GetColInfo(indexCol, col), S_OK);
|
|
TESTC_(m_pReferenceTable->GetColInfo(indexCol, col2), S_OK);
|
|
|
|
// build the foreign key constraint, use corresponding columns in tables
|
|
cons.AddColumn(col2.GetColID());
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
cons.SetReferencedTableID(&m_pReferenceTable->GetTableID());
|
|
|
|
// add the foreign key constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), DB_E_SCHEMAVIOLATION);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
int TCAddConstraint_FOREIGNKEY::Variation_38() {
|
|
TBEGIN
|
|
|
|
CLimitTable Table;
|
|
|
|
TESTC_(Table.CheckForeignKeyLimit(), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAddConstraint_FOREIGNKEY::Terminate()
|
|
{
|
|
if (m_pReferenceTable)
|
|
m_pReferenceTable->DropTable();
|
|
delete m_pReferenceTable;
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAddConstraint_CHECK)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAddConstraint_CHECK - Testcase for ITableDefinitionWithConstraints::AddConstraint used with DBCONSTRAINTTYPE_UNIQUE
|
|
//| Created: 7/29/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddConstraint_CHECK::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add simple check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_1()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
DBORDINAL rgNULLCols[] = {1};
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
Table.GetTableID().eKind? Table.GetTableID().uName.pwszName: NULL);
|
|
|
|
// get the first column of the table
|
|
cons.SetIsNotNULLCheckConstraint(&Table, rgNULLCols[0]);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
TEST2C_(hr = m_pIOpenRowset->OpenRowset(NULL, &Table.GetTableID(), NULL,
|
|
IID_IRowsetChange, 0, NULL, (IUnknown**)&pIRowsetChange), S_OK, E_NOINTERFACE);
|
|
TESTC_PROVIDER(S_OK == hr);
|
|
|
|
// try to insert a null value in a not null column
|
|
TESTC_(hr = Insert(0, pIRowsetChange, NUMELEM(rgNULLCols), rgNULLCols), DB_E_INTEGRITYVIOLATION);
|
|
|
|
TESTC_(Table.GetColInfo(rgNULLCols[0], col), S_OK);
|
|
TEST2C_(hr = DropColumnAndCheck(&Table.GetTableID(), col.GetColID()), S_OK, DB_E_DROPRESTRICTED);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add 2 check constraints on the same column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_2()
|
|
{
|
|
TBEGIN
|
|
CCheckCons cons;
|
|
DBORDINAL indexCol = 1;
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// get the first column of the table
|
|
TESTC_(cons.SetIsNotNULLCheckConstraint(&Table, indexCol), S_OK);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// change the name of the constraint helper object
|
|
CHECK(cons.MakeConstraintName(), S_OK);
|
|
|
|
// create the text of the constraint
|
|
TESTC_(cons.SetLTCheckConstraint(&Table, indexCol, 2), S_OK);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add check constraint for each column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
DBORDINAL indexCol;
|
|
HRESULT hrExpected = S_OK;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
for (indexCol = 0; indexCol < Table.CountColumnsOnTable(); indexCol++)
|
|
{
|
|
// get the first column of the table
|
|
TESTC_(Table.GetColInfo(indexCol+1, col), S_OK);
|
|
|
|
// change the name of the constraint helper object
|
|
cons.SetConstraintName(col.GetColName());
|
|
CHECK(cons.MakeConstraintName(), S_OK);
|
|
|
|
// create the text of the constraint
|
|
if (S_OK != cons.SetLTCheckConstraint(&Table, indexCol+1, 2))
|
|
CHECK(cons.SetIsNotNULLCheckConstraint(&Table, indexCol+1), S_OK);
|
|
|
|
// Check Constraints on BLOBs should fail
|
|
if (col.GetIsLong())
|
|
hrExpected = E_FAIL;
|
|
else
|
|
hrExpected = S_OK;
|
|
|
|
odtLog << col.GetColName() << "\t -> " << (hrExpected==S_OK ? "S_OK" : "E_FAIL") << "\n";
|
|
|
|
// add the constraint and check its addition
|
|
CHECK(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), hrExpected);
|
|
}
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Check constraint is always TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons(L"TRUE");
|
|
CWString wszText;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
wszText = col.GetColName();
|
|
wszText + L" IS NULL OR ";
|
|
wszText + col.GetColName();
|
|
wszText + L" IS NOT NULL";
|
|
cons.SetConstraintText((LPWSTR)(LPCWSTR)wszText);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Check constraint is always false
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_5()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons(L"FALSE");
|
|
CWString wszText;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
wszText = col.GetColName();
|
|
wszText + L" IS NULL AND ";
|
|
wszText + col.GetColName();
|
|
wszText + L" IS NOT NULL";
|
|
cons.SetConstraintText((LPWSTR)(LPCWSTR)wszText);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Long text for the check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_6()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
const DBORDINAL cTextLen = 1001;
|
|
WCHAR wszText[cTextLen];
|
|
CCol col;
|
|
CWString wszText1;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
wszText1 = col.GetColName();
|
|
wszText1 + L" IS NULL";
|
|
|
|
swprintf(wszText, L"%1000s", (LPCWSTR)wszText1);
|
|
cons.SetConstraintText(wszText);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Check constraint is made of white characters
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_7()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons(L" \t");
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), E_FAIL);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length for the table name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_8()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
WCHAR *pwszTableName = NULL;
|
|
|
|
// set a long table name
|
|
m_pTable->MakeTableName(NULL);
|
|
pwszTableName = BuildValidName(m_cMaxTableName, m_pTable->GetTableName());
|
|
TESTC_(Table.CreateTable(0, 0, pwszTableName), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// create the text of the constraint
|
|
CHECK(cons.SetLTCheckConstraint(&Table, 1, 5), S_OK);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszTableName);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create the constraint, drop it, readd it with different text
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_9()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
|
|
// create a table with an index
|
|
TESTC_(Table.CreateTable(0, 1), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// create the text of the constraint
|
|
CHECK(cons.SetLTCheckConstraint(&Table, 1, 5), S_OK);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// set a different text
|
|
CHECK(cons.SetIsNotNULLCheckConstraint(&Table, 2), S_OK);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use inexistent column names in the check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_10()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons(L"InexistentCol < 10");
|
|
CCol col;
|
|
|
|
// create a table with an index
|
|
TESTC_(Table.CreateTable(0, 1), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use qualified table column with different table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_11()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable Table2(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
WCHAR *pwszColValue = NULL;
|
|
CWString wszText;
|
|
HRESULT hr = S_OK;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
|
|
// create a table with an index
|
|
TESTC_(Table.CreateTable(0, 1), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
Table.BuildColumnDescs(&rgColumnDesc);
|
|
|
|
//Second table should have the same columns' names
|
|
Table2.SetColumnDesc(rgColumnDesc, Table.CountColumnsOnTable());
|
|
Table2.SetBuildColumnDesc(FALSE);
|
|
TESTC_(Table2.CreateTable(0, 1), S_OK);
|
|
Table2.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table2.GetTableName());
|
|
|
|
// get the first column of the table
|
|
TESTC_(Table2.GetColInfo(1 , col), S_OK);
|
|
|
|
// create the text of the constraint
|
|
TESTC_(Table.GetLiteralAndValue(col, &pwszColValue, rand(), col.GetColNum(), PRIMARY), S_OK);
|
|
wszText = Table2.GetTableName();
|
|
wszText + L".";
|
|
wszText + col.GetColName();
|
|
wszText + L" < ";
|
|
wszText + pwszColValue;
|
|
cons.SetConstraintText((LPWSTR)(LPCWSTR)wszText);
|
|
|
|
// add the constraint and check its addition
|
|
//Note: according to the spec provider can return E_FAIL or DB_E_NOCOLUMN when
|
|
// column referenced by pwszConstraintText does not exist
|
|
// DB_E_BADCONSTRAINTFORM can not be retunred in this case
|
|
//TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_BADCONSTRAINTFORM);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszColValue);
|
|
Table.DropTable();
|
|
Table2.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Set a check condition on an index column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
DBORDINAL indexCol = 1;
|
|
|
|
// create a table with an index
|
|
TESTC_(Table.CreateTable(0, indexCol), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
CHECK(cons.SetLTCheckConstraint(&Table, indexCol, 7), S_OK);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pwszConstraintText is NULL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_13()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
cons.SetConstraintText(NULL);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pwszConstraintText is an empty string
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_14()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons(L"");
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), E_FAIL);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_15()
|
|
{
|
|
CAddCheckConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort non retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_16()
|
|
{
|
|
CAddCheckConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_17()
|
|
{
|
|
CAddCheckConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit non retaining
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_18()
|
|
{
|
|
CAddCheckConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table is populated with rows that break the constraint to be added => DB_E_SCHEMAVIOLATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_CHECK::Variation_19()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
DBORDINAL rgNULLCols[1];
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NOT NULL";
|
|
|
|
TESTC_(Table.CreateTable(5, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITableDefinition,
|
|
Table.GetTableID().eKind? Table.GetTableID().uName.pwszName: NULL);
|
|
|
|
// get the first column of the table
|
|
TESTC_(Table.GetColInfo(1 , col), S_OK);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(col.GetColName()) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, col.GetColName());
|
|
wcscat(pwszConstraintText, wszText);
|
|
cons.SetConstraintText(pwszConstraintText);
|
|
|
|
// add a row with a NULL first column
|
|
TEST2C_(hr = m_pIOpenRowset->OpenRowset(NULL, &Table.GetTableID(), NULL,
|
|
IID_IRowsetChange, 0, NULL, (IUnknown**)&pIRowsetChange), S_OK, E_NOINTERFACE);
|
|
TESTC_PROVIDER(S_OK == hr);
|
|
|
|
// try to insert a null value in a not null column
|
|
rgNULLCols[0] = col.GetColNum();
|
|
TESTC_(hr = Insert(0, pIRowsetChange, NUMELEM(rgNULLCols), rgNULLCols), S_OK);
|
|
|
|
// try to add the constraint
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_SCHEMAVIOLATION);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
SAFE_FREE(pwszConstraintText);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
int TCAddConstraint_CHECK::Variation_20() {
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
DBCONSTRAINTDESC *pConsDesc = (DBCONSTRAINTDESC*)cons;
|
|
CCol col;
|
|
DBORDINAL indxCat = 0;
|
|
CCatalogs Catalogs(m_pIOpenRowset);
|
|
IDBProperties *pIDBProperties = NULL;
|
|
CPropSets PropSets;
|
|
WCHAR *pwszCurrentCatalog = NULL;
|
|
WCHAR *pwszQualTableName = NULL;
|
|
WCHAR *pwszCatalogName = NULL;
|
|
WCHAR *pwszSchemaName = NULL;
|
|
|
|
TESTC_PROVIDER(SettableProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, m_pIDBInitialize));
|
|
TESTC_PROVIDER(1 < Catalogs.cCatalogs());
|
|
|
|
// create a table and an index
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// select column
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// set DBID of the table to its qualified form
|
|
TESTC(DBKIND_NAME == Table.GetTableID().eKind);
|
|
|
|
TESTC(GetCatalogSchemaNames(Table.GetTableName(), &pwszCatalogName, &pwszSchemaName));
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(m_pTable->GetQualifiedName(pwszCatalogName, pwszSchemaName, Table.GetTableName(), &pwszQualTableName),S_OK);
|
|
Table.SetTableName(pwszQualTableName);
|
|
|
|
// change the current catalog
|
|
TESTC(GetProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, m_pIDBInitialize,
|
|
&pwszCurrentCatalog));
|
|
TESTC(NULL != pwszCurrentCatalog);
|
|
|
|
TESTC(VerifyInterface(m_pIDBInitialize, IID_IDBProperties, DATASOURCE_INTERFACE, (IUnknown**)&pIDBProperties));
|
|
|
|
if (0 == wcscmp(pwszCurrentCatalog, Catalogs[0]))
|
|
indxCat++;
|
|
|
|
CHECK(PropSets.AddProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, VT_BSTR, (LPVOID)Catalogs[indxCat]), S_OK);
|
|
TESTC_PROVIDER(S_OK == pIDBProperties->SetProperties(PropSets, PropSets));
|
|
|
|
// alloc memory for column array
|
|
cons.SetIsNotNULLCheckConstraint(&Table, col.GetColNum());
|
|
|
|
// try to make column unique
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
if (CHECK(PropSets.SetProperty(DBPROP_CURRENTCATALOG, DBPROPSET_DATASOURCE, VT_BSTR, (LPVOID)pwszCurrentCatalog), S_OK))
|
|
CHECK(pIDBProperties->SetProperties(PropSets, PropSets), S_OK);
|
|
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
SAFE_FREE(pwszQualTableName);
|
|
SAFE_FREE(pwszCurrentCatalog);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAddConstraint_CHECK::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAddConstraint_Deferrability)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAddConstraint_Deferrability - Testcase for ITableDefinitionWithConstraints::AddConstraint used with deferrability setting
|
|
//| Created: 7/29/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddConstraint_Deferrability::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Immediate unique constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_1()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table
|
|
TESTC_(Table.CreateTable(3, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// create an immediate unique constraint
|
|
TESTC_(AddUniqueConstraint(&Table, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// check that adding row with seed 2 again will fail
|
|
TESTC_(Table.Insert(2), DB_E_INTEGRITYVIOLATION);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Defferable unique constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_2()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table
|
|
TESTC_(Table.CreateTable(3, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// create a deferrable unique constraint
|
|
TEST2C_(hr = AddUniqueConstraint(&Table, 1, DBDEFERRABILITY_DEFERRABLE), S_OK, DB_E_BADDEFERRABILITY);
|
|
|
|
// check that adding row with seed 2 again will fail
|
|
if (S_OK == hr)
|
|
{
|
|
TESTC_(Table.Insert(2), DB_E_INTEGRITYVIOLATION);
|
|
}
|
|
else
|
|
odtLog << "Deferrable unique constraints are not supported\n";
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deffered unique constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_3()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table
|
|
TESTC_(Table.CreateTable(3, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// create an deferred unique constraint
|
|
TEST2C_(hr = AddUniqueConstraint(&Table, 1,
|
|
DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED), S_OK, DB_E_BADDEFERRABILITY);
|
|
|
|
// check that adding row with seed 2 again will fail
|
|
if (S_OK == hr)
|
|
{
|
|
TESTC_(Table.Insert(2), DB_E_INTEGRITYVIOLATION);
|
|
}
|
|
else
|
|
odtLog << "Deferred unique constraints are not supported\n";
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad deferrability value unique constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table
|
|
TESTC_(Table.CreateTable(0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// create a unique constraint
|
|
TESTC_(AddUniqueConstraint(&Table, 1,
|
|
~(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED)), DB_E_BADDEFERRABILITY);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Immediate primary key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_5()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 3), S_OK);
|
|
|
|
// create an immediate unique constraint
|
|
TESTC_(AddPrimaryKeyConstraint(&Table, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// check that adding row with seed 2 again will fail
|
|
TESTC_(Table.Insert(2), DB_E_INTEGRITYVIOLATION);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deferrable primary key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_6()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 3), S_OK);
|
|
|
|
// create a deferrable unique constraint
|
|
TEST2C_(hr = AddPrimaryKeyConstraint(&Table, 1, DBDEFERRABILITY_DEFERRABLE), S_OK, DB_E_BADDEFERRABILITY);
|
|
|
|
// check that adding row with seed 2 again will fail
|
|
if (S_OK == hr)
|
|
{
|
|
TESTC_(Table.Insert(2), DB_E_INTEGRITYVIOLATION);
|
|
}
|
|
else
|
|
odtLog << "Deferrable primary key constraints are not supported\n";
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deferred primary key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_7()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 3), S_OK);
|
|
|
|
// create an deferred primary key constraint
|
|
TEST2C_(hr = AddPrimaryKeyConstraint(&Table, 1,
|
|
DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED), S_OK, DB_E_BADDEFERRABILITY);
|
|
|
|
// check that adding row with seed 2 again will fail
|
|
if (S_OK == hr)
|
|
{
|
|
TESTC_(Table.Insert(2), DB_E_INTEGRITYVIOLATION);
|
|
}
|
|
else
|
|
odtLog << "Deferred primary key constraints are not supported\n";
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad deferrability value primary key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_8()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
// create a table
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// create a primary key constraint
|
|
TESTC_(AddPrimaryKeyConstraint(&Table, 1,
|
|
~(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED)), DB_E_BADDEFERRABILITY);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Immediate foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_9()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
// create a table
|
|
TESTC_(BaseTable.CreateTable(0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// create a unique constraint in the refereced table
|
|
TESTC_PROVIDER(S_OK == AddUniqueConstraint(&ReferencedTable, 1));
|
|
|
|
// create an immediate foreign key constraint
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType, DBUPDELRULE_NOACTION, DBUPDELRULE_NOACTION,
|
|
(DBDEFERRABILITY)0), S_OK);
|
|
|
|
// check that adding row with seed 2 again will fail
|
|
TESTC_(BaseTable.Insert(10), DB_E_INTEGRITYVIOLATION);
|
|
|
|
// check adding row in the referenced table is ok
|
|
TESTC_(ReferencedTable.Insert(10), S_OK);
|
|
TESTC_(BaseTable.Insert(10), S_OK);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deferrable foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_10()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
// create a table
|
|
TESTC_(BaseTable.CreateTable(0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// create a unique constraint in the refereced table
|
|
TESTC_PROVIDER(S_OK == AddUniqueConstraint(&ReferencedTable, 1));
|
|
|
|
// create a deferrable foreign key constraint
|
|
TEST2C_(hr = AddForeignKeyConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType, DBUPDELRULE_NOACTION, DBUPDELRULE_NOACTION,
|
|
DBDEFERRABILITY_DEFERRABLE), S_OK, DB_E_BADDEFERRABILITY);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// check that adding row with seed 2 again will fail
|
|
TESTC_(BaseTable.Insert(2), DB_E_INTEGRITYVIOLATION);
|
|
|
|
// check adding row in the referenced table is ok
|
|
TESTC_(ReferencedTable.Insert(2), S_OK);
|
|
TESTC_(BaseTable.Insert(2), S_OK);
|
|
}
|
|
else
|
|
odtLog << "Deferrable foreign key not supported\n";
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deferred foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_11()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
// create a table
|
|
TESTC_(BaseTable.CreateTable(0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// create a unique constraint in the refereced table
|
|
TESTC_PROVIDER(S_OK == AddUniqueConstraint(&ReferencedTable, 1));
|
|
|
|
// create a deferrable foreign key constraint
|
|
TEST2C_(hr = AddForeignKeyConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType, DBUPDELRULE_NOACTION, DBUPDELRULE_NOACTION,
|
|
DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED),
|
|
S_OK, DB_E_BADDEFERRABILITY);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// check that adding row with seed 2 again will fail
|
|
TESTC_(BaseTable.Insert(2), S_OK);
|
|
|
|
// check adding row in the referenced table is ok
|
|
TESTC_(ReferencedTable.Insert(2), S_OK);
|
|
TESTC_(BaseTable.Insert(2), S_OK);
|
|
}
|
|
else
|
|
odtLog << "Deferred foreign key not supported\n";
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad deferrability value foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBORDINAL rgBaseCol[] = {1};
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
// create a table
|
|
TESTC_(BaseTable.CreateTable(0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// create a unique constraint in the refereced table
|
|
TESTC_PROVIDER(S_OK == AddUniqueConstraint(&ReferencedTable, 1));
|
|
|
|
// create an immediate foreign key constraint
|
|
TESTC_(AddForeignKeyConstraint(&BaseTable, NUMELEM(rgBaseCol), rgBaseCol,
|
|
&ReferencedTable, NUMELEM(rgReferencedCol), rgReferencedCol,
|
|
m_SupportedMatchType, DBUPDELRULE_NOACTION, DBUPDELRULE_NOACTION,
|
|
~(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED)), DB_E_BADDEFERRABILITY);
|
|
|
|
// check adding row in the referenced table is ok
|
|
TESTC_(ReferencedTable.Insert(2), S_OK);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Immediate check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_13()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NULL";
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// get the first column of the table
|
|
TESTC_(Table.GetColInfo(1 , col), S_OK);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(col.GetColName()) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, col.GetColName());
|
|
wcscat(pwszConstraintText, wszText);
|
|
cons.SetConstraintText(pwszConstraintText);
|
|
cons.SetDeferrability((DBDEFERRABILITY)0);
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// add a row that does not have NULL in the checked column
|
|
TESTC_PROVIDER(2 < Table.CountColumnsOnTable());
|
|
TESTC_(Table.Insert(3), DB_E_INTEGRITYVIOLATION);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deferrable check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_14()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NULL";
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// get the first column of the table
|
|
TESTC_(Table.GetColInfo(1 , col), S_OK);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(col.GetColName()) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, col.GetColName());
|
|
wcscat(pwszConstraintText, wszText);
|
|
cons.SetConstraintText(pwszConstraintText);
|
|
cons.SetDeferrability(DBDEFERRABILITY_DEFERRABLE);
|
|
|
|
// add the constraint and check its addition
|
|
TEST2C_(hr = AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK, DB_E_BADDEFERRABILITY);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// add a row that does not have NULL in the checked column
|
|
TESTC_PROVIDER(2 < Table.CountColumnsOnTable());
|
|
TESTC_(Table.Insert(3), DB_E_INTEGRITYVIOLATION);
|
|
}
|
|
else
|
|
odtLog << "Deferrable check constraints are not supported\n";
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deferred check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_15()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NULL";
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// get the first column of the table
|
|
TESTC_(Table.GetColInfo(1 , col), S_OK);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(col.GetColName()) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, col.GetColName());
|
|
wcscat(pwszConstraintText, wszText);
|
|
cons.SetConstraintText(pwszConstraintText);
|
|
cons.SetDeferrability(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED);
|
|
|
|
// add the constraint and check its addition
|
|
TEST2C_(hr = AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK, DB_E_BADDEFERRABILITY);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// add a row that does not have NULL in the checked column
|
|
TESTC_(Table.Insert(3), S_OK);
|
|
}
|
|
else
|
|
odtLog << "Deferred check constraints are not supported\n";
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad deferrability value check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Deferrability::Variation_16()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NULL";
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// get the first column of the table
|
|
TESTC_(Table.GetColInfo(1 , col), S_OK);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(col.GetColName()) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, col.GetColName());
|
|
wcscat(pwszConstraintText, wszText);
|
|
cons.SetConstraintText(pwszConstraintText);
|
|
cons.SetDeferrability(~(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED));
|
|
|
|
// add the constraint and check its addition
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_BADDEFERRABILITY);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAddConstraint_Deferrability::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCCreateTableWithConstraints_NoConstraint)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCCreateTableWithConstraints_NoConstraint - Testcase for ITableDefinitionWithConstraints::AddConstraint used with deferrability setting
|
|
//| Created: 7/29/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCCreateTableWithConstraints_NoConstraint::Init()
|
|
{
|
|
ITableDefinitionWithConstraints *pITableDefinitionWithConstraints = NULL;
|
|
|
|
if(TCCreateTable::Init())
|
|
{
|
|
// check for ITableDefinition
|
|
if (!(m_hr=VerifyInterface(m_pIOpenRowset, IID_ITableDefinitionWithConstraints, SESSION_INTERFACE, (IUnknown**)&pITableDefinitionWithConstraints)))
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
SAFE_RELEASE(pITableDefinitionWithConstraints);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @member Create the table using ITableDefinition::CreateTable and
|
|
// check its creation
|
|
//---------------------------------------------------------------------
|
|
HRESULT TCCreateTableWithConstraints_NoConstraint::CreateAndCheckTable(
|
|
ITableDefinition *pITableDefinition, // [in] pointer to the ITableDefinition interface to be used
|
|
IUnknown *pUnkOuter, // [in] pointer to controlling unknown
|
|
DBID *pTableID, // [in] pointer to the input table ID
|
|
DBORDINAL cColumnDescs, // [in] the number of columns to be created
|
|
DBCOLUMNDESC *rgColumnDescs, // [in/out] array of columns to be created
|
|
REFIID riid, // [in] rowset interface to be returned
|
|
ULONG cPropertySets, // [in] number of roset property sets asked
|
|
DBPROPSET *rgPropertySets, // [in/out] array of rowset property sets
|
|
DBID **ppTableID, // [out] returned table ID
|
|
IUnknown **ppRowset // [out] pointer to outer interface
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
ITableDefinitionWithConstraints *pITDWC = NULL;
|
|
|
|
TESTC(NULL != pITableDefinition);
|
|
TESTC(VerifyInterface(pITableDefinition, IID_ITableDefinitionWithConstraints,
|
|
SESSION_INTERFACE, (IUnknown**)&pITDWC));
|
|
|
|
hr = CreateAndCheckTableWithConstraints(pITDWC, pUnkOuter, pTableID,
|
|
cColumnDescs, rgColumnDescs, 0, NULL,
|
|
riid, cPropertySets, rgPropertySets,
|
|
ppTableID, ppRowset);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pITDWC);
|
|
return hr;
|
|
} //TCCreateTableWithConstraints_NoConstraint::CreateAndCheckTable
|
|
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCCreateTableWithConstraints_NoConstraint::Terminate()
|
|
{
|
|
return(TCCreateTable::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCCreateTableWithConstraints)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCCreateTableWithConstraints - Testcase for ITableDefinitionWithConstraints::CreateTableWithConstraints when constraints are set
|
|
//| Created: 7/29/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCCreateTableWithConstraints::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create a table and multiple constraint of various types
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_1()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with a unique constraint (on a single column)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with a unique constraint (on multiple columns)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_3()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consUnique.AddColumn(&rgColumnDesc[3].dbcid);
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with a primary key constraint (on a single column)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_4()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CPrimaryKeyCons consPK;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// set a primary key constraint on the second column
|
|
consPK.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consPK,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with a primary key constraint (on multiple columns)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_5()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CPrimaryKeyCons consPK;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// set a primary key constraint on the second column
|
|
consPK.AddColumn(&rgColumnDesc[1].dbcid);
|
|
consPK.AddColumn(&rgColumnDesc[3].dbcid);
|
|
consPK.AddColumn(&rgColumnDesc[2].dbcid);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consPK,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with a foreign key constraint (single column)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_6()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBORDINAL indexCol = 2;
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consFK(NULL, m_SupportedMatchType);
|
|
CCol col;
|
|
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, indexCol, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(indexCol, col), S_OK);
|
|
consFK.AddColumn(col.GetColID());
|
|
consFK.AddForeignKeyColumn(&rgColumnDesc[indexCol-1].dbcid);
|
|
consFK.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
TESTC_(consFK.MakeConstraintName(), S_OK);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consFK,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with foreign key constraint defined on multiple keys
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_7()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBORDINAL rgColumns[] = {2, 1};
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consFK(NULL, m_SupportedMatchType);
|
|
CCol col;
|
|
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, NUMELEM(rgColumns), rgColumns, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(rgColumns[0], col), S_OK);
|
|
consFK.AddColumn(col.GetColID());
|
|
TESTC_(ReferencedTable.GetColInfo(rgColumns[1], col), S_OK);
|
|
consFK.AddColumn(col.GetColID());
|
|
|
|
consFK.AddForeignKeyColumn(&rgColumnDesc[rgColumns[0]-1].dbcid);
|
|
consFK.AddForeignKeyColumn(&rgColumnDesc[rgColumns[1]-1].dbcid);
|
|
|
|
consFK.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
TESTC_(consFK.MakeConstraintName(), S_OK);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consFK,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with a simple check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_8()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CCheckCons cons;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NOT NULL";
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// build constraint text
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(rgColumnDesc[0].dbcid.uName.pwszName) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, rgColumnDesc[0].dbcid.uName.pwszName);
|
|
wcscat(pwszConstraintText, wszText);
|
|
cons.SetConstraintText(pwszConstraintText);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, cons,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with multiple unique constraints defined
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CUniqueCons consUnique1;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
consUnique.MakeConstraintName();
|
|
|
|
// set second unique constraints on the firstcolumn
|
|
consUnique1.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consUnique1.MakeConstraintName();
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consUnique1);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with unique constraint and foreign key
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_10()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
consUnique.MakeConstraintName();
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
consForeignKey.MakeConstraintName();
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table with primary key and check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_11()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NOT NULL";
|
|
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
SetProperty(&rgColumnDesc[1].rgPropertySets, &rgColumnDesc[1].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// set a primary key constraint on the first column
|
|
consPK.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
// build constraint text
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[1].dbcid.eKind);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(rgColumnDesc[1].dbcid.uName.pwszName) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, rgColumnDesc[1].dbcid.uName.pwszName);
|
|
wcscat(pwszConstraintText, wszText);
|
|
consCheck.SetConstraintText(pwszConstraintText);
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consPK);
|
|
ConsDescArray.AddConsDesc(consCheck);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deferrable, immediate constraints
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
CCheckCons consCheck;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NULL";
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
HRESULT hr;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
consUnique.SetDeferrability(DBDEFERRABILITY_DEFERRABLE);
|
|
|
|
// try to create a table with a deferrable unique constraint
|
|
hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consUnique, IID_IRowset, 0, NULL, NULL, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// drop the table
|
|
CHECK(DropTableAndCheck(&TableID, m_pITableDefinition), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_BADDEFERRABILITY);
|
|
}
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consPrimaryKey.SetDeferrability(DBDEFERRABILITY_DEFERRABLE);
|
|
|
|
// try to create a table with a deferrable primary key constraint
|
|
hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey, IID_IRowset, 0, NULL, NULL, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// drop the table
|
|
CHECK(DropTableAndCheck(&TableID, m_pITableDefinition), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_BADDEFERRABILITY);
|
|
}
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
consForeignKey.SetDeferrability(DBDEFERRABILITY_DEFERRABLE);
|
|
|
|
// try to create a table with a deferrable foreign key constraint
|
|
hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey, IID_IRowset, 0, NULL, NULL, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// drop the table
|
|
CHECK(DropTableAndCheck(&TableID, m_pITableDefinition), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_BADDEFERRABILITY);
|
|
}
|
|
|
|
// build constraint text
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[4].dbcid.eKind);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(rgColumnDesc[4].dbcid.uName.pwszName) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, rgColumnDesc[4].dbcid.uName.pwszName);
|
|
wcscat(pwszConstraintText, wszText);
|
|
consCheck.SetConstraintText(pwszConstraintText);
|
|
consCheck.SetDeferrability(DBDEFERRABILITY_DEFERRABLE);
|
|
|
|
// try to create a table with a deferrable check constraint
|
|
hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consCheck, IID_IRowset, 0, NULL, NULL, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// drop the table
|
|
CHECK(DropTableAndCheck(&TableID, m_pITableDefinition), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_BADDEFERRABILITY);
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
DropTableAndCheck(&TableID);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Deferred constraints
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_13()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
CCheckCons consCheck;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NULL";
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
HRESULT hr;
|
|
CTable Table(m_pITableDefinition, (LPWSTR)gwszModuleName);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
consUnique.SetDeferrability(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED);
|
|
|
|
// try to create a table with a deferrable unique constraint
|
|
hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consUnique, IID_IRowset, 0, NULL, NULL, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// try to insert a duplicate value in the second column and check it is possible
|
|
Table.SetTableID(TableID);
|
|
if (CHECK(Table.GetTableColumnInfo(&TableID), S_OK))
|
|
{
|
|
CHECK(Table.Insert(1), S_OK);
|
|
CHECK(Table.Insert(1), S_OK);
|
|
}
|
|
// drop the table
|
|
CHECK(DropTableAndCheck(&TableID, m_pITableDefinition), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_BADDEFERRABILITY);
|
|
}
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consPrimaryKey.SetDeferrability(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED);
|
|
|
|
// try to create a table with a deferrable primary key constraint
|
|
hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey, IID_IRowset, 0, NULL, NULL, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// try to insert a duplicate value in the primary key column and check it is possible
|
|
Table.SetTableID(TableID);
|
|
if (CHECK(Table.GetTableColumnInfo(&TableID), S_OK))
|
|
{
|
|
CHECK(Table.Insert(1), S_OK);
|
|
CHECK(Table.Insert(1), S_OK);
|
|
}
|
|
// drop the table
|
|
CHECK(DropTableAndCheck(&TableID, m_pITableDefinition), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_BADDEFERRABILITY);
|
|
}
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
consForeignKey.SetDeferrability(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED);
|
|
|
|
// try to create a table with a deferrable foreign key constraint
|
|
hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey, IID_IRowset, 0, NULL, NULL, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// try to insert a row base table (referenced table is empty)
|
|
Table.SetTableID(TableID);
|
|
if (CHECK(Table.GetTableColumnInfo(&TableID), S_OK))
|
|
{
|
|
CHECK(Table.Insert(7), S_OK);
|
|
CHECK(Table.Insert(5), S_OK);
|
|
}
|
|
// drop the table
|
|
CHECK(DropTableAndCheck(&TableID, m_pITableDefinition), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_BADDEFERRABILITY);
|
|
}
|
|
|
|
// build constraint text
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[4].dbcid.eKind);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(rgColumnDesc[4].dbcid.uName.pwszName) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, rgColumnDesc[4].dbcid.uName.pwszName);
|
|
wcscat(pwszConstraintText, wszText);
|
|
consCheck.SetConstraintText(pwszConstraintText);
|
|
consCheck.SetDeferrability(DBDEFERRABILITY_DEFERRABLE | DBDEFERRABILITY_DEFERRED);
|
|
|
|
// try to create a table with a deferrable check constraint
|
|
hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consCheck, IID_IRowset, 0, NULL, NULL, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// try to insert a not null value in the checked column
|
|
Table.SetTableID(TableID);
|
|
if (CHECK(Table.GetTableColumnInfo(&TableID), S_OK))
|
|
{
|
|
CHECK(Table.Insert(1), S_OK);
|
|
CHECK(Table.Insert(10), S_OK);
|
|
}
|
|
// drop the table
|
|
CHECK(DropTableAndCheck(&TableID, m_pITableDefinition), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_BADDEFERRABILITY);
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pwszConstraintText);
|
|
DropTableAndCheck(&TableID);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_14()
|
|
{
|
|
CCreateTableWithConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort non retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_15()
|
|
{
|
|
CCreateTableWithConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_16()
|
|
{
|
|
CCreateTableWithConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit non retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints::Variation_17()
|
|
{
|
|
CCreateTableWithConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCCreateTableWithConstraints::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCCreateTableWithConstraints_Boundary)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCCreateTableWithConstraints_Boundary - Boundary and NULL testcase for ITableDefinitionWithConstraints::CreateTableWithConstraints
|
|
//| Created: 9/3/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCCreateTableWithConstraints_Boundary::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 0 < cConstraintDescs and NULL == rgConstraintDescs => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_1()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
3, NULL,
|
|
IID_IRowset, 0, NULL, NULL, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 0 == cConstraintDescs and NULL != rgConstraintDescs => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons cons;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
cons.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
0, cons,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(this->DropTableAndCheck(&TableID), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is NULL ppTableID is not NULL => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad DBKIND of a constraint ID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
ReleaseDBID(((DBCONSTRAINTDESC*)consPrimaryKey)->pConstraintID, FALSE);
|
|
((DBCONSTRAINTDESC*)consPrimaryKey)->pConstraintID->eKind = 0xb2;
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTID);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL pConstraintID in a constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_5()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
ReleaseDBID(((DBCONSTRAINTDESC*)consPrimaryKey)->pConstraintID, TRUE);
|
|
((DBCONSTRAINTDESC*)consPrimaryKey)->pConstraintID = NULL;
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL column list in a constraint, column size is not 0 => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_6()
|
|
{
|
|
// this tests rgColumnList for PK, FK and unique constraints
|
|
// as well as rgForeignKeyColumnList for FK
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CUniqueCons cons;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
DBCONSTRAINTDESC *pConsDesc;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
cons.AddColumn(&rgColumnDesc[0].dbcid);
|
|
pConsDesc = consUnique;
|
|
pConsDesc->cColumns = 2;
|
|
pConsDesc->rgColumnList = NULL;
|
|
ConsDescArray.AddConsDesc(cons);
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), E_INVALIDARG);
|
|
|
|
|
|
// set a primary key on the first column of the table
|
|
pConsDesc = consPrimaryKey;
|
|
pConsDesc->cColumns = 5;
|
|
pConsDesc->rgColumnList = NULL;
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), E_INVALIDARG);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
pConsDesc = consForeignKey;
|
|
pConsDesc->cColumns = 1;
|
|
pConsDesc->rgColumnList = NULL;
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), E_INVALIDARG);
|
|
|
|
// the same check for foreign key column list
|
|
consForeignKey.ReleaseForeignKeyColumnList();
|
|
pConsDesc->cForeignKeyColumns = 1;
|
|
pConsDesc->cColumns = 0;
|
|
consForeignKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty list of columns for a unique, primay key or foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_7()
|
|
{
|
|
// this tests rgColumnList for PK, FK and unique constraints
|
|
// as well as rgForeignKeyColumnList for FK
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CUniqueCons cons;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
cons.AddColumn(&rgColumnDesc[0].dbcid);
|
|
ConsDescArray.AddConsDesc(cons);
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
|
|
|
|
// set a primary key on the first column of the table
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
TEST2C_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), E_INVALIDARG, DB_E_BADCONSTRAINTFORM);
|
|
|
|
// the same check for foreign key column list
|
|
consForeignKey.ReleaseForeignKeyColumnList();
|
|
consForeignKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Non empty list of columns for a check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_8()
|
|
{
|
|
// this tests the case when rgColumnList or rgForeignKeyColumnList
|
|
// are not empty in a check constraint
|
|
TBEGIN
|
|
CCheckCons consCheck;
|
|
DBCONSTRAINTDESC *pcons = consCheck;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
WCHAR wszText[] = L" IS NOT NULL";
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
// create the text of the constraint
|
|
SAFE_FREE(pwszConstraintText);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(rgColumnDesc[0].dbcid.uName.pwszName) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, rgColumnDesc[0].dbcid.uName.pwszName);
|
|
wcscat(pwszConstraintText, wszText);
|
|
consCheck.SetConstraintText(pwszConstraintText);
|
|
|
|
// not empty rgColumnList
|
|
pcons->cColumns = 1;
|
|
pcons->rgColumnList = &rgColumnDesc[0].dbcid;
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consCheck,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
|
|
// not empty rgForeignKeyColumnList
|
|
pcons->cColumns = 0;
|
|
pcons->rgColumnList = NULL;
|
|
pcons->cForeignKeyColumns = 1;
|
|
pcons->rgForeignKeyColumnList = &rgColumnDesc[0].dbcid;
|
|
TEST2C_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consCheck,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM, E_INVALIDARG);
|
|
|
|
// not empty rgColumnList and rgForeignKeyColumnList
|
|
pcons->cColumns = 1;
|
|
pcons->rgColumnList = &rgColumnDesc[0].dbcid;
|
|
pcons->cForeignKeyColumns = 1;
|
|
pcons->rgForeignKeyColumnList = &rgColumnDesc[0].dbcid;
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consCheck,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
pcons->cColumns = 0;
|
|
pcons->rgColumnList = NULL;
|
|
pcons->cForeignKeyColumns = 0;
|
|
pcons->rgForeignKeyColumnList = NULL;
|
|
SAFE_FREE(pwszConstraintText);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Non empty list of foreign keys for a constraint that is not foreign key
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_9()
|
|
{
|
|
TBEGIN
|
|
CForeignKeyCons consFK;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
const DBORDINAL cColumns = 2;
|
|
DBID rgColumnList[cColumns];
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
rgColumnList[0].eKind = DBKIND_NAME;
|
|
rgColumnList[0].uName.pwszName = (LPWSTR)0x01234567;
|
|
rgColumnList[1].eKind = 0xfe;
|
|
rgColumnList[1].uName.pwszName = (LPWSTR)0x01234567;
|
|
|
|
// set up the unique constraint
|
|
consUnique.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
((DBCONSTRAINTDESC*)consUnique)->cForeignKeyColumns = cColumns;
|
|
((DBCONSTRAINTDESC*)consUnique)->rgForeignKeyColumnList = rgColumnList;
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consUnique)->cForeignKeyColumns = 0;
|
|
((DBCONSTRAINTDESC*)consUnique)->rgForeignKeyColumnList = NULL;
|
|
|
|
// set up the primary key constraint
|
|
consPK.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consPK.AddColumn(&rgColumnDesc[1].dbcid);
|
|
((DBCONSTRAINTDESC*)consPK)->cForeignKeyColumns = cColumns;
|
|
((DBCONSTRAINTDESC*)consPK)->rgForeignKeyColumnList = rgColumnList;
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPK,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consPK)->cForeignKeyColumns = 0;
|
|
((DBCONSTRAINTDESC*)consPK)->rgForeignKeyColumnList = NULL;
|
|
|
|
// set up the check constraint
|
|
consCheck.SetConstraintText(L"TRUE != FALSE");
|
|
((DBCONSTRAINTDESC*)consCheck)->cForeignKeyColumns = cColumns;
|
|
((DBCONSTRAINTDESC*)consCheck)->rgForeignKeyColumnList = rgColumnList;
|
|
TEST2C_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consCheck,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), E_INVALIDARG, DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
((DBCONSTRAINTDESC*)consCheck)->cForeignKeyColumns = 0;
|
|
((DBCONSTRAINTDESC*)consCheck)->rgForeignKeyColumnList = NULL;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc 0 < cForeignKeyColumns and NULL == rgForeignKeyColumnList => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_10()
|
|
{
|
|
// this tests rgColumnList for PK, FK and unique constraints
|
|
// as well as rgForeignKeyColumnList for FK
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons cons;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a simple foreign key constraint
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
consForeignKey.ReleaseForeignKeyColumnList();
|
|
((DBCONSTRAINTDESC*)consForeignKey)->cForeignKeyColumns = 1;
|
|
consForeignKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Constraint is not foreign key and pReferencedTableID is not NULL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_11()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPK;
|
|
CCheckCons consCheck;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the unique constraint
|
|
consUnique.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
|
|
DBID* pTempDBID = NULL;
|
|
|
|
DuplicateDBID(ReferencedTable.GetTableIDRef(), pTempDBID);
|
|
((DBCONSTRAINTDESC*)consUnique)->pReferencedTableID = pTempDBID;
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consUnique)->pReferencedTableID = NULL;
|
|
|
|
// set up the primary key constraint
|
|
consPK.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consPK.AddColumn(&rgColumnDesc[1].dbcid);
|
|
DuplicateDBID(ReferencedTable.GetTableIDRef(), pTempDBID);
|
|
((DBCONSTRAINTDESC*)consPK)->pReferencedTableID = pTempDBID;
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPK,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consPK)->pReferencedTableID = NULL;
|
|
|
|
// set up the check constraint
|
|
consCheck.SetConstraintText(L"TRUE != FALSE");
|
|
DuplicateDBID(ReferencedTable.GetTableIDRef(), pTempDBID);
|
|
((DBCONSTRAINTDESC*)consCheck)->pReferencedTableID = pTempDBID;
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consCheck,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
((DBCONSTRAINTDESC*)consCheck)->pReferencedTableID = NULL;
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL pReferencedTableID for a foreign key constraint (with and without cForeignKeyColumns being 0)
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
CCol col;
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
consForeignKey.SetReferencedTableID(NULL);
|
|
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
CHECK(consForeignKey.MakeConstraintName(), S_OK);
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTFORM);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL referenced table name for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_13()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
CCol col;
|
|
DBID ReferencedTableID;
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
ReferencedTableID.eKind = DBKIND_NAME;
|
|
ReferencedTableID.uName.pwszName = NULL;
|
|
consForeignKey.SetReferencedTableID(&ReferencedTableID);
|
|
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DB_NULLID *pReferencedTableID for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_14()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
CCol col;
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
consForeignKey.SetReferencedTableID((DBID*)&DB_NULLID);
|
|
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty string referenced table name for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_15()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
CCol col;
|
|
DBID ReferencedTableID;
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
ReferencedTableID.eKind = DBKIND_NAME;
|
|
ReferencedTableID.uName.pwszName = L"";
|
|
consForeignKey.SetReferencedTableID(&ReferencedTableID);
|
|
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length referenced table name for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_16()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
CCol col;
|
|
WCHAR *pwszTableName = NULL;
|
|
CUniqueCons cons;
|
|
|
|
// create support for foreign key constraint
|
|
ReferencedTable.MakeTableName(NULL);
|
|
pwszTableName = BuildValidName(m_cMaxTableName, ReferencedTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0, pwszTableName), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
CHECK(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
SAFE_FREE(pwszTableName);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Referenced table name longer than allowed for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_17()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
CCol col;
|
|
DBID ReferencedTableID;
|
|
|
|
// create support for foreign key constraint
|
|
ReferencedTable.MakeTableName(NULL);
|
|
ReferencedTableID.eKind = DBKIND_NAME;
|
|
ReferencedTableID.uName.pwszName = BuildValidName(m_cMaxTableName+1, ReferencedTable.GetTableName());
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
consForeignKey.SetReferencedTableID(&ReferencedTableID);
|
|
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
ReleaseDBID(&ReferencedTableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Illegal characters in the referenced table name for a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_18()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
CCol col;
|
|
DBID ReferencedTableID;
|
|
size_t m, n;
|
|
|
|
// create support for foreign key constraint
|
|
ReferencedTable.MakeTableName(NULL);
|
|
ReferencedTableID.eKind = DBKIND_NAME;
|
|
m = min(m_cMaxTableName, n=5+wcslen(ReferencedTable.GetTableName()));
|
|
ReferencedTableID.uName.pwszName = BuildInvalidName(m, ReferencedTable.GetTableName(), m_pwszInvalidTableChars);
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
consForeignKey.SetReferencedTableID(&ReferencedTableID);
|
|
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
ReleaseDBID(&ReferencedTableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad constraint type
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_19()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
DBCONSTRAINTDESC ConsDesc;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
|
|
// set up the check constraint
|
|
memset(&ConsDesc, 0, sizeof(DBCONSTRAINTDESC));
|
|
ConsDesc.ConstraintType = 0x4b;
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, &ConsDesc,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_BADCONSTRAINTTYPE);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent referenced table
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_20()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
DBID *pTableID = NULL;
|
|
|
|
// create support for foreign key constraint
|
|
ReferencedTable.MakeTableName(NULL);
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind
|
|
&& rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// set up the check constraint
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
consForeignKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
CHECK(CreateAndCheckTableWithConstraints(
|
|
m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL,
|
|
&pTableID, NULL), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty string for a column name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_21()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
DBID colid;
|
|
|
|
colid.eKind = DBKIND_NAME;
|
|
colid.uName.pwszName = L"";
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&colid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, NULL, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&colid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL, NULL, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&colid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL, NULL, NULL), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum length column name in a constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_22()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
WCHAR *pwszColName = NULL;
|
|
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// build the column name
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind);
|
|
pwszColName = rgColumnDesc[0].dbcid.uName.pwszName;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = BuildValidName(m_cMaxColName, pwszColName);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[0].dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), S_OK);
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), S_OK);
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), S_OK);
|
|
CHECK(DropTableAndCheck(pTableID), S_OK);
|
|
ReleaseDBID(pTableID, TRUE);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
SAFE_FREE(pwszColName);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid DBKIND for a column DBID of a constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_23()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
DBID dbcid;
|
|
|
|
dbcid.eKind = 0x3c;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
((DBCONSTRAINTDESC*)consUnique)->cColumns = 1;
|
|
((DBCONSTRAINTDESC*)consUnique)->rgColumnList = &dbcid;
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a primary key on the first column of the table
|
|
((DBCONSTRAINTDESC*)consPrimaryKey)->cColumns = 1;
|
|
((DBCONSTRAINTDESC*)consPrimaryKey)->rgColumnList = &dbcid;
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
((DBCONSTRAINTDESC*)consForeignKey)->cForeignKeyColumns = 1;
|
|
((DBCONSTRAINTDESC*)consForeignKey)->rgForeignKeyColumnList = &dbcid;
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
((DBCONSTRAINTDESC*)consUnique)->cColumns = 0;
|
|
((DBCONSTRAINTDESC*)consUnique)->rgColumnList = NULL;
|
|
((DBCONSTRAINTDESC*)consPrimaryKey)->cColumns = 0;
|
|
((DBCONSTRAINTDESC*)consPrimaryKey)->rgColumnList = NULL;
|
|
((DBCONSTRAINTDESC*)consForeignKey)->cForeignKeyColumns = 0;
|
|
((DBCONSTRAINTDESC*)consForeignKey)->rgForeignKeyColumnList = NULL;
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Column ID is DB_NULLID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_24()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
WCHAR *pwszColName = NULL;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// build the column name
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind);
|
|
pwszColName = rgColumnDesc[0].dbcid.uName.pwszName;
|
|
rgColumnDesc[0].dbcid.uName.pwszName = BuildValidName(m_cMaxColName, pwszColName);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on column DB_NULLID
|
|
consUnique.AddColumn((DBID*)&DB_NULLID);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a primary key on DB_NULLID
|
|
consPrimaryKey.AddColumn((DBID*)&DB_NULLID);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn((DBID*)&DB_NULLID);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
SAFE_FREE(pwszColName);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent column => DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_25()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc-1;
|
|
TESTC_PROVIDER(1 < m_cColumnDesc);
|
|
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[cColumnDesc].dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[cColumnDesc].dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[cColumnDesc].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
cColumnDesc = m_cColumnDesc;
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL column name => DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_26()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
DBID dbcid;
|
|
|
|
dbcid.eKind = DBKIND_NAME;
|
|
dbcid.uName.pwszName = NULL;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Column name exceeds maximum length name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_27()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
DBID dbcid;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind);
|
|
dbcid.eKind = DBKIND_NAME;
|
|
dbcid.uName.pwszName = BuildValidName(m_cMaxColName+1, rgColumnDesc[0].dbcid.uName.pwszName);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid column name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_28()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID *pTableID = NULL;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
DBID dbcid;
|
|
size_t m, n;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_PROVIDER(DBKIND_NAME == rgColumnDesc[0].dbcid.eKind);
|
|
m = min(m_cMaxColName, n=5+wcslen(rgColumnDesc[0].dbcid.uName.pwszName));
|
|
dbcid.eKind = DBKIND_NAME;
|
|
dbcid.uName.pwszName = BuildInvalidName(m, rgColumnDesc[0].dbcid.uName.pwszName, m_pwszInvalidColChars);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consUnique,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&dbcid);
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consPrimaryKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
CHECK(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, NULL,
|
|
cColumnDesc, rgColumnDesc,
|
|
1, consForeignKey,
|
|
IID_IRowset, 0, NULL, &pTableID, NULL), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Existent table name => DB_E_DUPLICATETABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_29()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), DB_E_DUPLICATETABLEID);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Same constraint name in 2 constraints => DB_E_DUPLICATECONSTRAINTID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_30()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
consPrimaryKey.SetConstraintName(consUnique.GetConstraintID()->uName.pwszName);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), DB_E_DUPLICATECONSTRAINTID);
|
|
|
|
CLEANUP:
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL pConstraintID in 2 constraints => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_31()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
ReleaseDBID(((DBCONSTRAINTDESC*)consUnique)->pConstraintID, TRUE);
|
|
((DBCONSTRAINTDESC*)consUnique)->pConstraintID = NULL;
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
ReleaseDBID(((DBCONSTRAINTDESC*)consPrimaryKey)->pConstraintID);
|
|
((DBCONSTRAINTDESC*)consPrimaryKey)->pConstraintID = NULL;
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Try to create table with constraints, but table already exists => DB_E_DUPLICATEDTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Boundary::Variation_32()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
TESTC_(hr = CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), DB_E_DUPLICATETABLEID);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCCreateTableWithConstraints_Boundary::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCDropConstraint)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCDropConstraint - Testcase for ITableDefinitionWithConstraints::DropConstraint
|
|
//| Created: 8/9/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCDropConstraint::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_1()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, NULL, cons), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID.uName.pwszName is NULL => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_2()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
DBCONSTRAINTDESC *pConsDesc = (DBCONSTRAINTDESC*)cons;
|
|
CCol col;
|
|
DBID TableID;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// alloc memory for column array
|
|
pConsDesc->cColumns = 1;
|
|
SAFE_ALLOC(pConsDesc->rgColumnList, DBID, pConsDesc->cColumns);
|
|
memset(pConsDesc->rgColumnList, 0, sizeof(pConsDesc->rgColumnList));
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
DuplicateDBID(*col.GetColID(), pConsDesc->rgColumnList);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = NULL;
|
|
TEST2C_(DropConstraintAndCheck(m_pITDWC, &TableID, pConsDesc->pConstraintID), DB_E_BADTABLEID, DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table name is empty => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
DBCONSTRAINTDESC *pConsDesc = (DBCONSTRAINTDESC*)cons;
|
|
CCol col;
|
|
DBID TableID;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// alloc memory for column array
|
|
pConsDesc->cColumns = 1;
|
|
SAFE_ALLOC(pConsDesc->rgColumnList, DBID, pConsDesc->cColumns);
|
|
memset(pConsDesc->rgColumnList, 0, sizeof(pConsDesc->rgColumnList));
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
DuplicateDBID(*col.GetColID(), pConsDesc->rgColumnList);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = L"";
|
|
TEST2C_(DropConstraintAndCheck(m_pITDWC, &TableID, pConsDesc->pConstraintID),
|
|
DB_E_BADTABLEID, DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Table name is not the one on which the column was created
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable Table2(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
DBCONSTRAINTDESC *pConsDesc = (DBCONSTRAINTDESC*)cons;
|
|
CCol col;
|
|
HRESULT hr;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
TESTC_(Table2.CreateTable(0, 0), S_OK);
|
|
Table2.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table2.GetTableName());
|
|
|
|
// alloc memory for column array
|
|
pConsDesc->cColumns = 1;
|
|
SAFE_ALLOC(pConsDesc->rgColumnList, DBID, pConsDesc->cColumns);
|
|
memset(pConsDesc->rgColumnList, 0, sizeof(pConsDesc->rgColumnList));
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
DuplicateDBID(*col.GetColID(), pConsDesc->rgColumnList);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TEST2C_(hr = DropConstraintAndCheck(m_pITDWC, &Table2.GetTableID(),
|
|
pConsDesc->pConstraintID), S_OK, E_FAIL);
|
|
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), pConsDesc->pConstraintID),
|
|
(S_OK == hr)? DB_E_BADTABLEID: S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
Table2.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent table name => DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_5()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CTable Table2(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
DBCONSTRAINTDESC *pConsDesc = (DBCONSTRAINTDESC*)cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// alloc memory for column array
|
|
pConsDesc->cColumns = 1;
|
|
SAFE_ALLOC(pConsDesc->rgColumnList, DBID, pConsDesc->cColumns);
|
|
memset(pConsDesc->rgColumnList, 0, sizeof(pConsDesc->rgColumnList));
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
DuplicateDBID(*col.GetColID(), pConsDesc->rgColumnList);
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(Table2.MakeTableName(NULL), S_OK);
|
|
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table2.GetTableID(), pConsDesc->pConstraintID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Maximum table name => S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_6()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
WCHAR *pwszTableName = NULL;
|
|
|
|
// create the base table with maximum name length
|
|
Table.MakeTableName(NULL);
|
|
pwszTableName = BuildValidName(m_cMaxTableName, Table.GetTableName());
|
|
TESTC_(Table.CreateTable(0, 0, pwszTableName), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(),
|
|
cons.GetConstraintID()), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
SAFE_FREE(pwszTableName);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid characters in table's name => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_7()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
size_t m, n;
|
|
DBID TableID;
|
|
|
|
// create the base table
|
|
TESTC_(Table.CreateTable(0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// set an invalid table name
|
|
m = min(m_cMaxColName, n=5+wcslen(Table.GetTableName()));
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = BuildInvalidName(m, Table.GetTableName(), m_pwszInvalidColChars);
|
|
|
|
// drop the constraint
|
|
TEST2C_(DropConstraintAndCheck(m_pITDWC, &TableID, cons.GetConstraintID()), DB_E_BADTABLEID, DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
ReleaseDBID(&TableID, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pConstraintID is NUL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_8()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint and recreate it
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pConstraintID is DB_NULLID => DB_E_NOCONSTRAINT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_9()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
cons.SetConstraintID((DBID*)&DB_NULLID);
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_NOCONSTRAINT);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid DBKIND in the constraint name => DB_E_NOCONSTRAINT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_10()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
ReleaseDBID(((DBCONSTRAINTDESC*)cons)->pConstraintID, FALSE);
|
|
((DBCONSTRAINTDESC*)cons)->pConstraintID->eKind = 0xa0;
|
|
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_NOCONSTRAINT);
|
|
|
|
CLEANUP:
|
|
((DBCONSTRAINTDESC*)cons)->pConstraintID->eKind = DBKIND_NAME;
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc NULL constraint name => DB_E_NOCONSTRAINT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_11()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
cons.SetConstraintName(NULL);
|
|
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_NOCONSTRAINT);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Constraint name is empty string => DB_E_NOCONSTRAINT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_12()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
cons.SetConstraintName(L"");
|
|
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_NOCONSTRAINT);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Inexistent constraint name => DB_E_NOCONSTRAINT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_13()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
cons.MakeConstraintName();
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_NOCONSTRAINT);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a constraint twice
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_14()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose a column and create a unique constraint on it
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), DB_E_NOCONSTRAINT);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a unique constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_15()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose a column and create a unique constraint on it
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a primary key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_16()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CPrimaryKeyCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// choose a column and create a primary key constraint on it
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a foreign key constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_17()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
CCol col;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(BaseTable.GetColInfo(1, col), S_OK);
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
cons.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a check constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_18()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NOT NULL";
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// choose a column and create a primary key constraint on it
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
// build constraint text
|
|
TESTC_PROVIDER(DBKIND_NAME == col.GetColID()->eKind);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(col.GetColID()->uName.pwszName) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, col.GetColID()->uName.pwszName);
|
|
wcscat(pwszConstraintText, wszText);
|
|
cons.SetConstraintText(pwszConstraintText);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
SAFE_FREE(pwszConstraintText);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create several constraints, drop a single constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_19()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBID TableID;
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray;
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
TableID.eKind = DBKIND_NAME;
|
|
TableID.uName.pwszName = m_pTable->GetTableName();
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray.AddConsDesc(consUnique);
|
|
ConsDescArray.AddConsDesc(consForeignKey);
|
|
ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
TESTC_(CreateAndCheckTableWithConstraints(m_pITDWC, NULL, &TableID, cColumnDesc, rgColumnDesc,
|
|
ConsDescArray, ConsDescArray,
|
|
IID_IRowset, 0, NULL, NULL, NULL), S_OK);
|
|
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &TableID, consForeignKey), S_OK);
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &TableID, consUnique), S_OK);
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &TableID, consPrimaryKey), S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(DropTableAndCheck(&TableID), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop a unique constraint in the referenced table, after the foreign key constraint was added
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_20()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
CUniqueCons consUnique;
|
|
CUniqueCons consUnique1;
|
|
CCol col;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
consUnique.SetConstraint(&ReferencedTable, 1);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &ReferencedTable.GetTableID(), consUnique), S_OK);
|
|
|
|
consUnique1.SetConstraint(&ReferencedTable, 2);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &ReferencedTable.GetTableID(), consUnique1), S_OK);
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(BaseTable.GetColInfo(1, col), S_OK);
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
cons.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
// drop the unique constraints on the referenced table
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &ReferencedTable.GetTableID(), consUnique),
|
|
DB_E_DROPRESTRICTED);
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &ReferencedTable.GetTableID(), consUnique1),
|
|
S_OK);
|
|
|
|
// drop the foreign key constraint on the base table
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
// drop the unique constraint on the referenced table
|
|
CHECK(DropConstraintAndCheck(m_pITDWC, &ReferencedTable.GetTableID(), consUnique),
|
|
S_OK);
|
|
|
|
CLEANUP:
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Try to drop a unique constraint while a rowset is opened on the table => DB_E_TABLEINUSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_21()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
HRESULT hr;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose a column and create a unique constraint on it
|
|
TESTC_(Table.GetColInfo(3, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// open a rowset on the table
|
|
CHECK(Table.Insert(7), S_OK);
|
|
CHECK(Table.Insert(7), DB_E_INTEGRITYVIOLATION);
|
|
TESTC_(hr = m_pIOpenRowset->OpenRowset(NULL, &Table.GetTableID(), NULL,
|
|
IID_IRowsetChange, 0, NULL, (IUnknown**)&pIRowsetChange), S_OK);
|
|
|
|
// drop the constraint
|
|
TEST2C_(hr = DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons),
|
|
S_OK, DB_E_TABLEINUSE);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
odtLog << "Constraint was dropped\n";
|
|
CHECK(Table.Insert(7), S_OK);
|
|
}
|
|
else
|
|
CHECK(Table.Insert(7), DB_E_INTEGRITYVIOLATION);
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc *pTableID is DB_NULLID => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_22()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TEST2C_(DropConstraintAndCheck(m_pITDWC, (DBID*)&DB_NULLID, cons), DB_E_BADTABLEID, DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid DBKIND in pTableID => DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_23()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
DBID TableID;
|
|
|
|
TESTC_(Table.CreateTable(0, 0), S_OK);
|
|
Table.AddInfoFromColumnsSchemaRowset(m_pITDWC, Table.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
// drop the constraint
|
|
TableID.eKind = 0x44;
|
|
TEST2C_(DropConstraintAndCheck(m_pITDWC, &TableID, cons), DB_E_BADTABLEID, DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Try to drop a check constraint while a rowset is opened on the table => DB_E_TABLEINUSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_24()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CCheckCons cons;
|
|
CCol col;
|
|
WCHAR *pwszConstraintText = NULL;
|
|
WCHAR wszText[] = L" IS NOT NULL";
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// choose a column and create a primary key constraint on it
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
// build constraint text
|
|
TESTC_PROVIDER(DBKIND_NAME == col.GetColID()->eKind);
|
|
SAFE_ALLOC(pwszConstraintText, WCHAR, 1 + wcslen(col.GetColID()->uName.pwszName) + wcslen(wszText));
|
|
wcscpy(pwszConstraintText, col.GetColID()->uName.pwszName);
|
|
wcscat(pwszConstraintText, wszText);
|
|
cons.SetConstraintText(pwszConstraintText);
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(m_pIOpenRowset->OpenRowset(NULL, &Table.GetTableID(), NULL,
|
|
IID_IRowsetChange, 0, NULL, (IUnknown**)&pIRowsetChange), S_OK);
|
|
|
|
// drop the constraint
|
|
TEST2C_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK, DB_E_TABLEINUSE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
Table.DropTable();
|
|
SAFE_FREE(pwszConstraintText);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Try to drop a pk constraint while a rowset is opened on the table => DB_E_TABLEINUSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_25()
|
|
{
|
|
TBEGIN
|
|
CTable Table(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
CPrimaryKeyCons cons;
|
|
CCol col;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&Table, 0), S_OK);
|
|
|
|
// choose a column and create a primary key constraint on it
|
|
TESTC_(Table.GetColInfo(1, col), S_OK);
|
|
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(m_pIOpenRowset->OpenRowset(NULL, &Table.GetTableID(), NULL,
|
|
IID_IRowsetChange, 0, NULL, (IUnknown**)&pIRowsetChange), S_OK);
|
|
|
|
// drop the constraint
|
|
TEST2C_(DropConstraintAndCheck(m_pITDWC, &Table.GetTableID(), cons), S_OK, DB_E_TABLEINUSE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
Table.DropTable();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Try to drop a fk constraint while a rowset is opened on the table => DB_E_TABLEINUSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_26()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CForeignKeyCons cons(NULL, m_SupportedMatchType);
|
|
CCol col;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(BaseTable.GetColInfo(1, col), S_OK);
|
|
cons.AddForeignKeyColumn(col.GetColID());
|
|
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
cons.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(m_pIOpenRowset->OpenRowset(NULL, &BaseTable.GetTableID(), NULL,
|
|
IID_IRowsetChange, 0, NULL, (IUnknown**)&pIRowsetChange), S_OK);
|
|
|
|
// drop the constraint
|
|
TEST2C_(DropConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK, DB_E_TABLEINUSE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Both pTableID and pConstraintID are NULL => E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_27()
|
|
{
|
|
TBEGIN
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CUniqueCons cons;
|
|
CCol col;
|
|
IRowsetChange *pIRowsetChange = NULL;
|
|
|
|
TESTC_(BaseTable.CreateTable(0, 0), S_OK);
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(BaseTable.GetColInfo(1, col), S_OK);
|
|
// Add constraint
|
|
cons.AddColumn(col.GetColID());
|
|
|
|
TESTC_(AddConstraintAndCheck(m_pITDWC, &BaseTable.GetTableID(), cons), S_OK);
|
|
|
|
TESTC_(m_pIOpenRowset->OpenRowset(NULL, &BaseTable.GetTableID(), NULL,
|
|
IID_IRowsetChange, 0, NULL, (IUnknown**)&pIRowsetChange), S_OK);
|
|
|
|
// drop the constraint
|
|
TESTC_(DropConstraintAndCheck(m_pITDWC, NULL, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
CHECK(BaseTable.DropTable(), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_28()
|
|
{
|
|
CDropConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort non retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_29()
|
|
{
|
|
CDropConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
TRUE, // Abort
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_30()
|
|
{
|
|
CDropConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
TRUE // Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Commit non retain
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint::Variation_31()
|
|
{
|
|
CDropConsTxnAdapter TxnAdapter(this);
|
|
CTransactionLocal TxnLocal;
|
|
|
|
return TxnLocal.DoTransactionTest(m_pITDWC, &TxnAdapter,
|
|
TRUE, // DDL
|
|
FALSE, // Commit
|
|
FALSE // Non Retaining
|
|
);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCDropConstraint::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAddConstraint_Multithreading)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAddConstraint_Multithreading - Testcase for ITableDefinitionWithConstraints::AddConstraint used in multithreaded calls
|
|
//| Created: 9/14/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAddConstraint_Multithreading::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Thread funtion for TCAddConstraint_Multithreading
|
|
//---------------------------------------------------------------------
|
|
unsigned TCAddConstraint_Multithreading::MyThreadProc(ULONG i)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (i>= nThreads)
|
|
return 0;
|
|
|
|
Sleep(0); // switch the context
|
|
|
|
hr = m_pITDWC->AddConstraint(m_prgTableID[i], &m_rgConstraintDesc[i]);
|
|
Sleep(0); // switch the context
|
|
|
|
m_rgResult[i] = hr;
|
|
return 1;
|
|
} //TCAddConstraint_Multithreading::MyThreadProc
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Each thread creates a different constraint
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Multithreading::Variation_1()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL cThreads = nThreads;
|
|
CConsDesc *pConsDesc = NULL;
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
ULONG i;
|
|
|
|
DBORDINAL rgCol[] = {1};
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_DUPLICATECONSTRAINTID,
|
|
DB_E_BADCONSTRAINTID,
|
|
DB_E_BADCONSTRAINTTYPE,
|
|
DB_E_BADUPDATEDELETERULE,
|
|
DB_E_BADMATCHTYPE,
|
|
DB_E_BADDEFERRABILITY,
|
|
DB_E_BADCONSTRAINTFORM,
|
|
DB_E_NOCOLUMN,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(m_pITDWC);
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
SAFE_ALLOC(m_prgTableID, DBID*, nThreads);
|
|
SAFE_ALLOC(m_rgConstraintDesc, DBCONSTRAINTDESC, nThreads);
|
|
memset(m_rgConstraintDesc, 0, nThreads * sizeof(DBCONSTRAINTDESC));
|
|
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
m_prgTableID[i] = &BaseTable.GetTableIDRef();
|
|
if (0 == i)
|
|
{
|
|
pConsDesc = new CPrimaryKeyCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CPrimaryKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else if (i%2)
|
|
{
|
|
pConsDesc = new CUniqueCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CUniqueCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else
|
|
{
|
|
pConsDesc = new CForeignKeyCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CForeignKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1, rgCol, &ReferencedTable, 1, rgCol, m_SupportedMatchType), S_OK);
|
|
}
|
|
|
|
pConsDesc->MakeConstraintName();
|
|
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// start the threads
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
if (!CHECK(m_rgResult[i], S_OK))
|
|
{
|
|
if ( m_rgConstraintDesc[i].pConstraintID
|
|
&& DBKIND_NAME == m_rgConstraintDesc[i].pConstraintID->eKind
|
|
&& m_rgConstraintDesc[i].pConstraintID->uName.pwszName)
|
|
odtLog << "Constraint " << m_rgConstraintDesc[i].pConstraintID->uName.pwszName << " failed to be added\n";
|
|
else
|
|
odtLog << "Constraint no " << i << " failed to be added\n";
|
|
|
|
COMPARE(CheckResult(m_rgResult[i], cValidHRes, rgValidHRes), TRUE);
|
|
}
|
|
else
|
|
{
|
|
// get all the constraints associated with the table
|
|
if ( m_prgTableID[i]
|
|
&& DBKIND_NAME == m_prgTableID[i]->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, m_prgTableID[i]->uName.pwszName, NULL, NULL, NULL), S_OK))
|
|
{
|
|
CHECK(Constraints.CheckIncludedConstraints(1, &m_rgConstraintDesc[i]), S_OK);
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
SAFE_FREE(m_prgTableID);
|
|
CHECK(FreeConstraintDesc(&cThreads, &m_rgConstraintDesc, TRUE), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Some of the threads try to create the same constraint name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Multithreading::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL cThreads = nThreads;
|
|
CConsDesc *pConsDesc = NULL;
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
ULONG i;
|
|
|
|
const ULONG cSameName = 5;
|
|
DBORDINAL cDuplicates = 0;
|
|
|
|
DBORDINAL rgCol[] = {1};
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_DUPLICATECONSTRAINTID,
|
|
DB_E_BADCONSTRAINTID,
|
|
DB_E_BADCONSTRAINTTYPE,
|
|
DB_E_BADUPDATEDELETERULE,
|
|
DB_E_BADMATCHTYPE,
|
|
DB_E_BADDEFERRABILITY,
|
|
DB_E_BADCONSTRAINTFORM,
|
|
DB_E_NOCOLUMN,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(m_pITDWC);
|
|
|
|
TESTC_PROVIDER(cSameName <= nThreads);
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
SAFE_ALLOC(m_prgTableID, DBID*, nThreads);
|
|
SAFE_ALLOC(m_rgConstraintDesc, DBCONSTRAINTDESC, nThreads);
|
|
memset(m_rgConstraintDesc, 0, nThreads * sizeof(DBCONSTRAINTDESC));
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
m_prgTableID[i] = &BaseTable.GetTableIDRef();
|
|
|
|
if (0 == i)
|
|
{
|
|
pConsDesc = new CPrimaryKeyCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CPrimaryKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else if (i%2)
|
|
{
|
|
pConsDesc = new CUniqueCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CUniqueCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else
|
|
{
|
|
pConsDesc = new CForeignKeyCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CForeignKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1, rgCol, &ReferencedTable, 1, rgCol, m_SupportedMatchType), S_OK);
|
|
}
|
|
|
|
if (0 == i || i >= cSameName)
|
|
pConsDesc->MakeConstraintName();
|
|
else
|
|
// several constraints have the same name
|
|
pConsDesc->SetConstraintID(m_rgConstraintDesc[0].pConstraintID);
|
|
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// start threads
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
if (S_OK != m_rgResult[i])
|
|
{
|
|
COMPARE(CompareDBID(*m_rgConstraintDesc[0].pConstraintID,
|
|
*m_rgConstraintDesc[i].pConstraintID), TRUE);
|
|
|
|
if (CHECK(m_rgResult[i], DB_E_DUPLICATECONSTRAINTID))
|
|
cDuplicates++;
|
|
|
|
if ( m_rgConstraintDesc[i].pConstraintID
|
|
&& DBKIND_NAME == m_rgConstraintDesc[i].pConstraintID->eKind
|
|
&& m_rgConstraintDesc[i].pConstraintID->uName.pwszName)
|
|
odtLog << "Constraint " << m_rgConstraintDesc[i].pConstraintID->uName.pwszName << " failed to be added\n";
|
|
else
|
|
odtLog << "Constraint no " << i << " failed to be added\n";
|
|
}
|
|
else
|
|
{
|
|
// get all the constraints associated with the table
|
|
if ( m_prgTableID[i]
|
|
&& DBKIND_NAME == m_prgTableID[i]->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, m_prgTableID[i]->uName.pwszName, NULL, NULL, NULL), S_OK))
|
|
{
|
|
CHECK(Constraints.CheckIncludedConstraints(1, &m_rgConstraintDesc[i]), S_OK);
|
|
}
|
|
}
|
|
}
|
|
|
|
// exactly cSameName - 1 ops should have failed
|
|
TESTC(cSameName - 1 == cDuplicates);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
SAFE_FREE(m_prgTableID);
|
|
CHECK(FreeConstraintDesc(&cThreads, &m_rgConstraintDesc, TRUE), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Unique constraints with disjoint columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Multithreading::Variation_3()
|
|
{
|
|
TBEGIN
|
|
ULONG cThreads = nThreads;
|
|
CConsDesc *pConsDesc = NULL;
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
ULONG i;
|
|
DBORDINAL iCol;
|
|
DBORDINAL cConsDescs = 0;
|
|
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_DUPLICATECONSTRAINTID,
|
|
DB_E_BADCONSTRAINTID,
|
|
DB_E_BADCONSTRAINTTYPE,
|
|
DB_E_BADUPDATEDELETERULE,
|
|
DB_E_BADMATCHTYPE,
|
|
DB_E_BADDEFERRABILITY,
|
|
DB_E_BADCONSTRAINTFORM,
|
|
DB_E_NOCOLUMN,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(m_pITDWC);
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
TESTC_PROVIDER(nThreads <= BaseTable.CountColumnsOnTable());
|
|
BaseTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, BaseTable.GetTableName());
|
|
|
|
SAFE_ALLOC(m_prgTableID, DBID*, nThreads);
|
|
SAFE_ALLOC(m_rgConstraintDesc, DBCONSTRAINTDESC, nThreads);
|
|
memset(m_rgConstraintDesc, 0, nThreads * sizeof(DBCONSTRAINTDESC));
|
|
for (cThreads=0, iCol=1; iCol <= BaseTable.CountColumnsOnTable() && cThreads < nThreads; iCol++)
|
|
{
|
|
CCol col;
|
|
|
|
TESTC_(BaseTable.GetColInfo(iCol, col), S_OK);
|
|
|
|
// Generally, setting unique constraints on BLOBs fail
|
|
// Note: col.GetColumnSize returns length for string data types and we need size in bytes
|
|
// so multiply ColumnSize by 2 for WSTR
|
|
|
|
if (col.GetIsLong() ||
|
|
(col.GetIsFixedLength() && (col.GetColumnSize() * (col.GetProviderType()==DBTYPE_WSTR ? 2:1) > cMaxColLengthPerCons)))
|
|
continue;
|
|
|
|
m_rgResult[cThreads] = -1;
|
|
m_prgTableID[cThreads] = &BaseTable.GetTableIDRef();
|
|
|
|
pConsDesc = new CUniqueCons(m_rgConstraintDesc+cThreads);
|
|
|
|
TESTC_(((CUniqueCons*)pConsDesc)->SetConstraint(&BaseTable, iCol), S_OK);
|
|
pConsDesc->MakeConstraintName();
|
|
|
|
rgThreadParam[cThreads].pObject = this;
|
|
rgThreadParam[cThreads].i = cThreads;
|
|
cThreads++;
|
|
}
|
|
cConsDescs = cThreads;
|
|
|
|
// start threads
|
|
for (i=0; i<cThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(cThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< cThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i< cThreads; i++)
|
|
{
|
|
if (CHECK(m_rgResult[i], S_OK))
|
|
{
|
|
// get all the constraints associated with the table
|
|
if ( m_prgTableID[i]
|
|
&& DBKIND_NAME == m_prgTableID[i]->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, m_prgTableID[i]->uName.pwszName, NULL, NULL, NULL), S_OK))
|
|
{
|
|
CHECK(Constraints.CheckIncludedConstraints(1, &m_rgConstraintDesc[i]), S_OK);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
SAFE_FREE(m_prgTableID);
|
|
CHECK(FreeConstraintDesc(&cConsDescs, &m_rgConstraintDesc, TRUE), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Unique constraints with overlapping columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Multithreading::Variation_4()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL cThreads = nThreads;
|
|
CConsDesc *pConsDesc = NULL;
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
ULONG i;
|
|
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_DUPLICATECONSTRAINTID,
|
|
DB_E_BADCONSTRAINTID,
|
|
DB_E_BADCONSTRAINTTYPE,
|
|
DB_E_BADUPDATEDELETERULE,
|
|
DB_E_BADMATCHTYPE,
|
|
DB_E_BADDEFERRABILITY,
|
|
DB_E_BADCONSTRAINTFORM,
|
|
DB_E_NOCOLUMN,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(m_pITDWC);
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
TESTC_PROVIDER(nThreads <= BaseTable.CountColumnsOnTable());
|
|
|
|
SAFE_ALLOC(m_prgTableID, DBID*, nThreads);
|
|
SAFE_ALLOC(m_rgConstraintDesc, DBCONSTRAINTDESC, nThreads);
|
|
memset(m_rgConstraintDesc, 0, nThreads * sizeof(DBCONSTRAINTDESC));
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
m_prgTableID[i] = &BaseTable.GetTableIDRef();
|
|
|
|
pConsDesc = new CUniqueCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CUniqueCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
pConsDesc->MakeConstraintName();
|
|
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// start threads
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
if (CHECK(m_rgResult[i], S_OK))
|
|
{
|
|
// get all the constraints associated with the table
|
|
if ( m_prgTableID[i]
|
|
&& DBKIND_NAME == m_prgTableID[i]->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, m_prgTableID[i]->uName.pwszName, NULL, NULL, NULL), S_OK))
|
|
{
|
|
CHECK(Constraints.CheckIncludedConstraints(1, &m_rgConstraintDesc[i]), S_OK);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
SAFE_FREE(m_prgTableID);
|
|
CHECK(FreeConstraintDesc(&cThreads, &m_rgConstraintDesc, TRUE), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc All constraint IDs are generated by the provider
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAddConstraint_Multithreading::Variation_5()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL cThreads = nThreads;
|
|
CConsDesc *pConsDesc = NULL;
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
ULONG i;
|
|
|
|
DBORDINAL rgCol[] = {1};
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_DUPLICATECONSTRAINTID,
|
|
DB_E_BADCONSTRAINTID,
|
|
DB_E_BADCONSTRAINTTYPE,
|
|
DB_E_BADUPDATEDELETERULE,
|
|
DB_E_BADMATCHTYPE,
|
|
DB_E_BADDEFERRABILITY,
|
|
DB_E_BADCONSTRAINTFORM,
|
|
DB_E_NOCOLUMN,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(m_pITDWC);
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
SAFE_ALLOC(m_prgTableID, DBID*, nThreads);
|
|
SAFE_ALLOC(m_rgConstraintDesc, DBCONSTRAINTDESC, nThreads);
|
|
memset(m_rgConstraintDesc, 0, nThreads * sizeof(DBCONSTRAINTDESC));
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
m_prgTableID[i] = &BaseTable.GetTableIDRef();
|
|
|
|
if (0 == i)
|
|
{
|
|
pConsDesc = new CPrimaryKeyCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CPrimaryKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else if (i%2)
|
|
{
|
|
pConsDesc = new CUniqueCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CUniqueCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else
|
|
{
|
|
pConsDesc = new CForeignKeyCons(m_rgConstraintDesc+i);
|
|
TESTC_(((CForeignKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1, rgCol, &ReferencedTable, 1, rgCol, m_SupportedMatchType), S_OK);
|
|
}
|
|
|
|
pConsDesc->SetConstraintID(NULL);
|
|
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// start the threads
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
if (CHECK(m_rgResult[i], S_OK))
|
|
{
|
|
// get all the constraints associated with the table
|
|
if ( m_prgTableID[i]
|
|
&& DBKIND_NAME == m_prgTableID[i]->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, m_prgTableID[i]->uName.pwszName, NULL, NULL, NULL), S_OK)
|
|
&& m_rgConstraintDesc[i].pConstraintID
|
|
)
|
|
{
|
|
CHECK(Constraints.CheckIncludedConstraints(1, &m_rgConstraintDesc[i]), S_OK);
|
|
}
|
|
}
|
|
}
|
|
|
|
COMPARE(Constraints.GetConstrNo(), nThreads);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
SAFE_FREE(m_prgTableID);
|
|
CHECK(FreeConstraintDesc(&cThreads, &m_rgConstraintDesc, TRUE), S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAddConstraint_Multithreading::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCDropConstraint_Multithreading)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCDropConstraint_Multithreading - Multithreading test case for ITableDefinitionWithConstraints::DropConstraints
|
|
//| Created: 9/16/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCDropConstraint_Multithreading::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Thread funtion for TCDropConstraint_Multithreading
|
|
//---------------------------------------------------------------------
|
|
unsigned TCDropConstraint_Multithreading::MyThreadProc(ULONG i)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (i>= nThreads)
|
|
return 0;
|
|
|
|
Sleep(0); // switch the context
|
|
|
|
hr = m_pITDWC->DropConstraint(m_prgTableID[i], m_prgConstraintID[i]);
|
|
Sleep(0); // switch the context
|
|
|
|
m_rgResult[i] = hr;
|
|
return 1;
|
|
} //TCDropConstraint_Multithreading::MyThreadProc
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Each thread drops a different constraint => all S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint_Multithreading::Variation_1()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL cThreads = nThreads;
|
|
CConsDesc *pConsDesc = NULL;
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
ULONG i;
|
|
DBCONSTRAINTDESC *rgConstraintDesc = NULL;
|
|
DBORDINAL rgCol[] = {1};
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_NOCONSTRAINT,
|
|
DB_E_BADTABLEID,
|
|
DB_E_DROPRESTRICTED,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(m_pITDWC);
|
|
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
SAFE_ALLOC(m_prgTableID, DBID*, nThreads);
|
|
SAFE_ALLOC(rgConstraintDesc, DBCONSTRAINTDESC, nThreads);
|
|
SAFE_ALLOC(m_prgConstraintID, DBID*, nThreads);
|
|
memset(rgConstraintDesc, 0, nThreads * sizeof(DBCONSTRAINTDESC));
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
m_prgTableID[i] = &BaseTable.GetTableIDRef();
|
|
|
|
// create a constraint
|
|
if (0 == i)
|
|
{
|
|
pConsDesc = new CPrimaryKeyCons(rgConstraintDesc+i);
|
|
TESTC_(((CPrimaryKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else if (i%2)
|
|
{
|
|
pConsDesc = new CUniqueCons(rgConstraintDesc+i);
|
|
TESTC_(((CUniqueCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else
|
|
{
|
|
pConsDesc = new CForeignKeyCons(rgConstraintDesc+i);
|
|
TESTC_(((CForeignKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1, rgCol, &ReferencedTable, 1, rgCol, m_SupportedMatchType), S_OK);
|
|
}
|
|
|
|
pConsDesc->MakeConstraintName();
|
|
TESTC_(m_pITDWC->AddConstraint(m_prgTableID[i], &rgConstraintDesc[i]), S_OK);
|
|
|
|
m_prgConstraintID[i] = rgConstraintDesc[i].pConstraintID;
|
|
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// start the threads
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
if (!CHECK(m_rgResult[i], S_OK))
|
|
{
|
|
if ( rgConstraintDesc[i].pConstraintID
|
|
&& DBKIND_NAME == rgConstraintDesc[i].pConstraintID->eKind
|
|
&& rgConstraintDesc[i].pConstraintID->uName.pwszName)
|
|
odtLog << "Constraint " << rgConstraintDesc[i].pConstraintID->uName.pwszName << " failed to be added\n";
|
|
else
|
|
odtLog << "Constraint no " << i << " failed to be dropped\n";
|
|
|
|
COMPARE(CheckResult(m_rgResult[i], cValidHRes, rgValidHRes), TRUE);
|
|
}
|
|
else
|
|
{
|
|
// get all the constraints associated with the table
|
|
if ( m_prgTableID[i]
|
|
&& DBKIND_NAME == m_prgTableID[i]->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, m_prgTableID[i]->uName.pwszName, NULL, NULL, NULL), S_OK))
|
|
{
|
|
COMPARE(NULL == Constraints[m_prgConstraintID[i]], TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
SAFE_FREE(m_prgTableID);
|
|
CHECK(FreeConstraintDesc(&cThreads, &rgConstraintDesc, TRUE), S_OK);
|
|
SAFE_FREE(m_prgConstraintID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Some threads try to drop the same constraint => S_OK and DB_E_NOCONSTRAINT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCDropConstraint_Multithreading::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL cThreads = nThreads;
|
|
CConsDesc *pConsDesc = NULL;
|
|
CTable ReferencedTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
CTable BaseTable(m_pITDWC, (LPWSTR)gwszModuleName);
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
ULONG i;
|
|
DBCONSTRAINTDESC *rgConstraintDesc = NULL;
|
|
DBORDINAL rgCol[] = {1};
|
|
HRESULT rgValidHRes[] = { S_OK,
|
|
E_FAIL,
|
|
E_INVALIDARG,
|
|
DB_E_NOCONSTRAINT,
|
|
DB_E_BADTABLEID,
|
|
DB_E_DROPRESTRICTED,
|
|
DB_E_NOTABLE,
|
|
DB_E_TABLEINUSE,
|
|
DB_SEC_E_PERMISSIONDENIED,
|
|
XACT_E_XTIONEXISTS,
|
|
DB_E_SCHEMAVIOLATION
|
|
};
|
|
ULONG cValidHRes = NUMELEM(rgValidHRes);
|
|
CConstraints Constraints(m_pITDWC);
|
|
|
|
DBORDINAL ulFailed = 0;
|
|
const DBORDINAL cSameName = 5;
|
|
|
|
TESTC_PROVIDER(cSameName <= nThreads);
|
|
TESTC_(CreateTableWithNoNullableColumns(&BaseTable, 0), S_OK);
|
|
TESTC_(ReferencedTable.CreateTable(0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1), S_OK);
|
|
|
|
SAFE_ALLOC(m_prgTableID, DBID*, nThreads);
|
|
SAFE_ALLOC(rgConstraintDesc, DBCONSTRAINTDESC, nThreads);
|
|
SAFE_ALLOC(m_prgConstraintID, DBID*, nThreads);
|
|
memset(rgConstraintDesc, 0, nThreads * sizeof(DBCONSTRAINTDESC));
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
m_rgResult[i] = -1;
|
|
m_prgTableID[i] = &BaseTable.GetTableIDRef();
|
|
|
|
// create a constraint
|
|
if (0 == i)
|
|
{
|
|
pConsDesc = new CPrimaryKeyCons(rgConstraintDesc+i);
|
|
TESTC_(((CPrimaryKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else if (i%2)
|
|
{
|
|
pConsDesc = new CUniqueCons(rgConstraintDesc+i);
|
|
TESTC_(((CUniqueCons*)pConsDesc)->SetConstraint(&BaseTable, 1), S_OK);
|
|
}
|
|
else
|
|
{
|
|
pConsDesc = new CForeignKeyCons(rgConstraintDesc+i);
|
|
TESTC_(((CForeignKeyCons*)pConsDesc)->SetConstraint(&BaseTable, 1, rgCol, &ReferencedTable, 1, rgCol, m_SupportedMatchType), S_OK);
|
|
}
|
|
|
|
pConsDesc->MakeConstraintName();
|
|
TESTC_(m_pITDWC->AddConstraint(m_prgTableID[i], &rgConstraintDesc[i]), S_OK);
|
|
|
|
if (i < cSameName)
|
|
m_prgConstraintID[i] = rgConstraintDesc[0].pConstraintID;
|
|
else
|
|
m_prgConstraintID[i] = rgConstraintDesc[i].pConstraintID;
|
|
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// start the threads
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
if (S_OK != m_rgResult[i])
|
|
{
|
|
CHECK(m_rgResult[i], DB_E_NOCONSTRAINT);
|
|
ulFailed++;
|
|
|
|
if ( rgConstraintDesc[i].pConstraintID
|
|
&& DBKIND_NAME == rgConstraintDesc[i].pConstraintID->eKind
|
|
&& rgConstraintDesc[i].pConstraintID->uName.pwszName)
|
|
odtLog << "Constraint " << rgConstraintDesc[i].pConstraintID->uName.pwszName << " failed to be added\n";
|
|
else
|
|
odtLog << "Constraint no " << i << " failed to be dropped\n";
|
|
|
|
COMPARE(CheckResult(m_rgResult[i], cValidHRes, rgValidHRes), TRUE);
|
|
}
|
|
else
|
|
{
|
|
// get all the constraints associated with the table
|
|
if ( m_prgTableID[i]
|
|
&& DBKIND_NAME == m_prgTableID[i]->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, m_prgTableID[i]->uName.pwszName, NULL, NULL, NULL), S_OK))
|
|
{
|
|
COMPARE(NULL == Constraints[m_prgConstraintID[i]], TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
TESTC(cSameName - 1 == ulFailed);
|
|
|
|
CLEANUP:
|
|
BaseTable.DropTable();
|
|
ReferencedTable.DropTable();
|
|
SAFE_FREE(m_prgTableID);
|
|
CHECK(FreeConstraintDesc(&cThreads, &rgConstraintDesc, TRUE), S_OK);
|
|
SAFE_FREE(m_prgConstraintID);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCDropConstraint_Multithreading::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCCreateTableWithConstraints_Multithreading)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCCreateTableWithConstraints_Multithreading - Multithreading test case for ITableDefinitionWithConstraints::CreateTableWithConstraints
|
|
//| Created: 9/17/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCCreateTableWithConstraints_Multithreading::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCITableDefinition::Init())
|
|
// }}
|
|
{
|
|
if (m_pITDWC == NULL)
|
|
{
|
|
odtLog << "ITableDefinitionWithConstraints is not supported.\n";
|
|
return TEST_SKIPPED;
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// @cmember Thread funtion for TCCreateTableWithConstraints_Multithreading
|
|
//---------------------------------------------------------------------
|
|
unsigned TCCreateTableWithConstraints_Multithreading::MyThreadProc(ULONG i)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (i>= nThreads)
|
|
return 0;
|
|
|
|
Sleep(0); // switch the context
|
|
|
|
hr = m_pITDWC->CreateTableWithConstraints(
|
|
m_rgThreadParams[i].m_pUnkOuter,
|
|
m_rgThreadParams[i].m_pTableID,
|
|
m_rgThreadParams[i].m_cColumnDescs,
|
|
m_rgThreadParams[i].m_rgColumnDescs,
|
|
m_rgThreadParams[i].m_cConstraintDescs,
|
|
m_rgThreadParams[i].m_rgConstraintDescs,
|
|
*m_rgThreadParams[i].m_piid,
|
|
m_rgThreadParams[i].m_cPropertySets,
|
|
m_rgThreadParams[i].m_rgPropertySets,
|
|
m_rgThreadParams[i].m_ppTableID,
|
|
m_rgThreadParams[i].m_ppRowset
|
|
);
|
|
Sleep(0); // switch the context
|
|
|
|
m_rgThreadParams[i].m_hr = hr;
|
|
return 1;
|
|
} //TCCreateTableWithConstraints_Multithreading::MyThreadProc
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Each thread builds different table => all S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Multithreading::Variation_1()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray[nThreads];
|
|
ULONG i;
|
|
CCol col;
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
CConstraints Constraints(m_pITDWC);
|
|
|
|
m_rgThreadParams = NULL;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
m_rgThreadParams = new CCTWCThreadParam[nThreads];
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
|
|
m_rgThreadParams[i].m_hr = E_FAIL;
|
|
m_rgThreadParams[i].m_op = CREATETABLE_CONSTRAINTS;
|
|
|
|
m_rgThreadParams[i].m_pUnkOuter = NULL;
|
|
m_rgThreadParams[i].m_pTableID = NULL;
|
|
|
|
m_rgThreadParams[i].m_cColumnDescs = cColumnDesc;
|
|
m_rgThreadParams[i].m_rgColumnDescs = rgColumnDesc;
|
|
|
|
// create the array of constraints
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray[i].AddConsDesc(consUnique);
|
|
ConsDescArray[i].AddConsDesc(consForeignKey);
|
|
ConsDescArray[i].AddConsDesc(consPrimaryKey);
|
|
|
|
m_rgThreadParams[i].m_cConstraintDescs = ConsDescArray[i];
|
|
m_rgThreadParams[i].m_rgConstraintDescs = ConsDescArray[i];
|
|
|
|
m_rgThreadParams[i].m_piid = NULL;
|
|
m_rgThreadParams[i].m_cPropertySets = 0;
|
|
m_rgThreadParams[i].m_rgPropertySets= NULL;
|
|
|
|
SAFE_ALLOC(m_rgThreadParams[i].m_ppTableID, DBID*, 1);
|
|
//*m_rgThreadParams[i].m_ppTableID = NULL;
|
|
m_rgThreadParams[i].m_ppRowset = NULL;
|
|
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// start the threads
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
DBID *pTableID = NULL;
|
|
|
|
if (m_rgThreadParams[i].m_ppTableID)
|
|
pTableID = (*m_rgThreadParams[i].m_ppTableID);
|
|
else if (m_rgThreadParams[i].m_pTableID)
|
|
pTableID = m_rgThreadParams[i].m_pTableID;
|
|
|
|
if (CHECK(m_rgThreadParams[i].m_hr, S_OK))
|
|
{
|
|
COMPARE(NULL != pTableID, TRUE);
|
|
|
|
// get all the constraints associated with the table
|
|
if ( pTableID
|
|
&& DBKIND_NAME == pTableID->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, pTableID->uName.pwszName, NULL, NULL, NULL), S_OK))
|
|
{
|
|
CHECK(Constraints.CheckIncludedConstraints(m_rgThreadParams[i].m_cConstraintDescs, m_rgThreadParams[i].m_rgConstraintDescs), S_OK);
|
|
}
|
|
|
|
// drop the newly created table
|
|
CHECK(m_pITableDefinition->DropTable(pTableID), S_OK);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
delete [] m_rgThreadParams;
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Some threads build the same table => S_OK and DB_E_DUPLICATETABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCCreateTableWithConstraints_Multithreading::Variation_2()
|
|
{
|
|
TBEGIN
|
|
CTable ReferencedTable(m_pThisTestModule->m_pIUnknown2, (LPWSTR)gwszModuleName);
|
|
DBCOLUMNDESC *rgColumnDesc = NULL;
|
|
DBORDINAL cColumnDesc = 0;
|
|
CConsDescArray ConsDescArray[nThreads];
|
|
ULONG i;
|
|
CCol col;
|
|
|
|
unsigned rgIDThread[nThreads];
|
|
HANDLE hrgThread[nThreads];
|
|
CInParam rgThreadParam[nThreads];
|
|
CConstraints Constraints(m_pITDWC);
|
|
WCHAR *pwszBaseName = NULL;
|
|
|
|
WCHAR number[3];
|
|
DBORDINAL cSameName = 5;
|
|
DBORDINAL cDuplicates = 0;
|
|
|
|
TESTC_PROVIDER(cSameName <= nThreads);
|
|
m_rgThreadParams = NULL;
|
|
|
|
DuplicateColumnDesc(m_rgColumnDesc, m_cColumnDesc, &rgColumnDesc);
|
|
cColumnDesc = m_cColumnDesc;
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(rgColumnDesc, cColumnDesc);
|
|
SetProperty(&rgColumnDesc[0].rgPropertySets, &rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(ReferencedTable.CreateTable(0, 0), S_OK);
|
|
ReferencedTable.AddInfoFromColumnsSchemaRowset(m_pITDWC, ReferencedTable.GetTableName());
|
|
// make the referenced columns unique
|
|
TESTC_(AddUniqueConstraint(&ReferencedTable, 1, (DBDEFERRABILITY)0), S_OK);
|
|
|
|
m_pTable->MakeTableName(NULL);
|
|
pwszBaseName = m_pTable->GetTableName();
|
|
|
|
m_rgThreadParams = new CCTWCThreadParam[nThreads];
|
|
for (i=0; i< nThreads; i++)
|
|
{
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_SupportedMatchType);
|
|
|
|
m_rgThreadParams[i].m_hr = E_FAIL;
|
|
m_rgThreadParams[i].m_op = CREATETABLE_CONSTRAINTS;
|
|
|
|
m_rgThreadParams[i].m_pUnkOuter = NULL;
|
|
|
|
SAFE_ALLOC(m_rgThreadParams[i].m_pTableID, DBID, 1);
|
|
m_rgThreadParams[i].m_pTableID->eKind = DBKIND_NAME;
|
|
|
|
SAFE_ALLOC(m_rgThreadParams[i].m_pTableID->uName.pwszName, WCHAR,
|
|
(3+wcslen(pwszBaseName)));
|
|
wcscpy(m_rgThreadParams[i].m_pTableID->uName.pwszName, pwszBaseName);
|
|
swprintf(number, L"%02d", (i < cSameName)? 0: i);
|
|
wcscat(m_rgThreadParams[i].m_pTableID->uName.pwszName, number);
|
|
|
|
m_rgThreadParams[i].m_cColumnDescs = cColumnDesc;
|
|
m_rgThreadParams[i].m_rgColumnDescs = rgColumnDesc;
|
|
|
|
// create the array of constraints
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&rgColumnDesc[0].dbcid);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(ReferencedTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&ReferencedTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
ConsDescArray[i].AddConsDesc(consUnique);
|
|
ConsDescArray[i].AddConsDesc(consForeignKey);
|
|
ConsDescArray[i].AddConsDesc(consPrimaryKey);
|
|
|
|
m_rgThreadParams[i].m_cConstraintDescs = ConsDescArray[i];
|
|
m_rgThreadParams[i].m_rgConstraintDescs = ConsDescArray[i];
|
|
|
|
m_rgThreadParams[i].m_piid = NULL;
|
|
m_rgThreadParams[i].m_cPropertySets = 0;
|
|
m_rgThreadParams[i].m_rgPropertySets= NULL;
|
|
|
|
m_rgThreadParams[i].m_ppTableID = NULL;
|
|
m_rgThreadParams[i].m_ppRowset = NULL;
|
|
|
|
rgThreadParam[i].pObject = this;
|
|
rgThreadParam[i].i = i;
|
|
}
|
|
|
|
// start the threads
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
hrgThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadProc,
|
|
(void*)&rgThreadParam[i],
|
|
0,
|
|
&rgIDThread[i]); // input param
|
|
TESTC(0 != hrgThread[i]);
|
|
}
|
|
|
|
WaitForMultipleObjects(nThreads, (CONST HANDLE*)hrgThread, TRUE, 1000);
|
|
Sleep(1000);
|
|
for (i=0; i< nThreads; i++)
|
|
CloseHandle(hrgThread[i]);
|
|
|
|
for (i=0; i<nThreads; i++)
|
|
{
|
|
DBID *pTableID = NULL;
|
|
|
|
if (m_rgThreadParams[i].m_ppTableID)
|
|
pTableID = (*m_rgThreadParams[i].m_ppTableID);
|
|
else if (m_rgThreadParams[i].m_pTableID)
|
|
pTableID = m_rgThreadParams[i].m_pTableID;
|
|
|
|
if (S_OK == m_rgThreadParams[i].m_hr)
|
|
{
|
|
COMPARE(NULL != pTableID, TRUE);
|
|
|
|
// get all the constraints associated with the table
|
|
if ( pTableID
|
|
&& DBKIND_NAME == pTableID->eKind
|
|
&& CHECK(Constraints.GetConstraints(NULL, NULL, pTableID->uName.pwszName, NULL, NULL, NULL), S_OK))
|
|
{
|
|
CHECK(Constraints.CheckIncludedConstraints(m_rgThreadParams[i].m_cConstraintDescs, m_rgThreadParams[i].m_rgConstraintDescs), S_OK);
|
|
}
|
|
|
|
// drop the newly created table
|
|
CHECK(m_pITableDefinition->DropTable(pTableID), S_OK);
|
|
}
|
|
else
|
|
{
|
|
if (CHECK(m_rgThreadParams[i].m_hr, DB_E_DUPLICATETABLEID))
|
|
cDuplicates++;
|
|
}
|
|
}
|
|
|
|
TESTC(cDuplicates + 1 == cSameName);
|
|
|
|
CLEANUP:
|
|
delete [] m_rgThreadParams;
|
|
CHECK(ReferencedTable.DropTable(), S_OK);
|
|
ReleaseColumnDesc(rgColumnDesc, cColumnDesc);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCCreateTableWithConstraints_Multithreading::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCITableDefinition::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAddConstraintTxnAdapter class
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
BOOL CAddConstraintTxnAdapter::BeforeTransaction()
|
|
{
|
|
TBEGIN
|
|
|
|
// create a table and populate it
|
|
TESTC_(pTCITableDefinition()->CreateTableWithNoNullableColumns(&m_Table, 0, 0), S_OK);
|
|
m_Table.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_Table.GetTableName());
|
|
|
|
// get the list of the constraints on the table
|
|
m_pConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pConstraints->GetConstraints(NULL, NULL, m_Table.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddConstraintTxnAdapter::BeforeTransaction
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAddUniqueConsTxnAdapter class
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
BOOL CAddUniqueConsTxnAdapter::BeforeTransaction()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
|
|
TESTC(CAddConstraintTxnAdapter::BeforeTransaction());
|
|
|
|
// select column
|
|
TESTC_(m_Table.GetColInfo(1, col), S_OK);
|
|
|
|
// add the constraint
|
|
m_pCons = new CUniqueCons();
|
|
((CUniqueCons*)m_pCons)->AddColumn(col.GetColID());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddUniqueConsTxnAdapter::BeforeTransaction
|
|
|
|
|
|
|
|
HRESULT CAddUniqueConsTxnAdapter::InsideTransactionScope()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
CCol col;
|
|
|
|
CHECK(CAddConstraintTxnAdapter::InsideTransactionScope(), S_OK);
|
|
|
|
// create a table
|
|
TESTC_(pTCITableDefinition()->CreateTableWithNoNullableColumns(&m_TransactedTable, 0, 0), S_OK);
|
|
m_TransactedTable.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_TransactedTable.GetTableName());
|
|
|
|
// get the list of the constraints on the table
|
|
m_pTxnConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pTxnConstraints->GetConstraints(NULL, NULL, m_TransactedTable.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
// select column
|
|
TESTC_(m_TransactedTable.GetColInfo(1, col), S_OK);
|
|
|
|
// add the constraint
|
|
m_pTransactedTableCons= new CUniqueCons();
|
|
((CUniqueCons*)m_pTransactedTableCons)->AddColumn(col.GetColID());
|
|
|
|
hr = m_pTCITableDefinition->AddConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_TransactedTable.GetTableID(),
|
|
*m_pTransactedTableCons);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //CAddUniqueConsTxnAdapter::InsideTransactionScope
|
|
|
|
|
|
|
|
HRESULT CAddUniqueConsTxnAdapter::InsideTransactionOnDDLLock()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
CCol col;
|
|
|
|
CHECK(CAddConstraintTxnAdapter::InsideTransactionOnDDLLock(), S_OK);
|
|
|
|
// create a table and populate it
|
|
TESTC_(pTCITableDefinition()->CreateTableWithNoNullableColumns(&m_TransactedTable, 0, 0), S_OK);
|
|
m_TransactedTable.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_TransactedTable.GetTableName());
|
|
|
|
// select column
|
|
TESTC_(m_TransactedTable.GetColInfo(1, col), S_OK);
|
|
|
|
// add the constraint
|
|
m_pTransactedTableCons = new CUniqueCons();
|
|
((CUniqueCons*)m_pTransactedTableCons)->AddColumn(col.GetColID());
|
|
|
|
// get the list of the constraints on the table
|
|
m_pTxnConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pTxnConstraints->GetConstraints(NULL, NULL, m_TransactedTable.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
hr = m_pTCITableDefinition->pITDWC()->AddConstraint(
|
|
&m_TransactedTable.GetTableID(),
|
|
*m_pTransactedTableCons);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //CAddUniqueConsTxnAdapter::InsideTransactionOnDDLLock
|
|
|
|
|
|
|
|
BOOL CAddUniqueConsTxnAdapter::CheckCompletion()
|
|
{
|
|
TBEGIN
|
|
|
|
ASSERT(m_pCons);
|
|
TESTC(CAddConstraintTxnAdapter::CheckCompletion());
|
|
|
|
// check unique constraint here
|
|
TESTC_(m_Table.Insert(5), S_OK);
|
|
TESTC_(m_Table.Insert(5), DB_E_INTEGRITYVIOLATION);
|
|
|
|
ASSERT(m_pTransactedTableCons);
|
|
TESTC_(m_TransactedTable.Insert(5), S_OK);
|
|
TESTC_(m_TransactedTable.Insert(5), DB_E_INTEGRITYVIOLATION);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddUniqueConsTxnAdapter::CheckCompletion
|
|
|
|
|
|
|
|
BOOL CAddUniqueConsTxnAdapter::CheckRollBack()
|
|
{
|
|
TBEGIN
|
|
|
|
ASSERT(m_pCons);
|
|
TESTC(CAddConstraintTxnAdapter::CheckRollBack());
|
|
|
|
// check unique constraint here
|
|
TESTC_(m_Table.Insert(5), S_OK);
|
|
TESTC_(m_Table.Insert(5), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddUniqueConsTxnAdapter::CheckRollBack
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAddPrimaryKeyConsTxnAdapter class
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
BOOL CAddPrimaryKeyConsTxnAdapter::BeforeTransaction()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
|
|
TESTC(CAddConstraintTxnAdapter::BeforeTransaction());
|
|
|
|
// select column
|
|
TESTC_(m_Table.GetColInfo(1, col), S_OK);
|
|
|
|
// add the constraint
|
|
m_pCons = new CPrimaryKeyCons();
|
|
((CPrimaryKeyCons*)m_pCons)->AddColumn(col.GetColID());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddPrimaryKeyConsTxnAdapter::BeforeTransaction
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAddFKConsTxnAdapter class
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL CAddFKConsTxnAdapter::BeforeTransaction()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
CUniqueCons uniqueCons;
|
|
|
|
// create a reference table and populate it
|
|
TESTC_(m_ReferencedTable.CreateTable(4, 0), S_OK);
|
|
m_ReferencedTable.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_ReferencedTable.GetTableName());
|
|
|
|
// add unique constraint on the first column
|
|
TESTC_(m_ReferencedTable.GetColInfo(1, col), S_OK);
|
|
uniqueCons.AddColumn(col.GetColID());
|
|
CHECK(m_pTCITableDefinition->AddConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_ReferencedTable.GetTableID(), uniqueCons), S_OK);
|
|
|
|
// create a table and populate it
|
|
TESTC_(m_Table.CreateTable(4, 0), S_OK);
|
|
m_Table.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_Table.GetTableName());
|
|
|
|
// get the list of the constraints on the table
|
|
m_pConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pConstraints->GetConstraints(NULL, NULL, m_Table.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
// prepare the constraint
|
|
m_pCons = new CForeignKeyCons();
|
|
|
|
// select column to be foreign key
|
|
TESTC_(m_Table.GetColInfo(1, col), S_OK);
|
|
((CForeignKeyCons*)m_pCons)->AddForeignKeyColumn(col.GetColID());
|
|
TESTC_(m_ReferencedTable.GetColInfo(1, col), S_OK);
|
|
((CForeignKeyCons*)m_pCons)->AddColumn(col.GetColID());
|
|
((CForeignKeyCons*)m_pCons)->SetReferencedTableID(&m_ReferencedTable.GetTableID());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddFKConsTxnAdapter::BeforeTransaction
|
|
|
|
|
|
|
|
|
|
HRESULT CAddFKConsTxnAdapter::InsideTransactionScope()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
CCol col;
|
|
|
|
CHECK(CAddConstraintTxnAdapter::InsideTransactionScope(), S_OK);
|
|
|
|
// create a table and populate it
|
|
TESTC_(pTCITableDefinition()->CreateTableWithNoNullableColumns(&m_TransactedTable, 0, 0), S_OK);
|
|
m_TransactedTable.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_TransactedTable.GetTableName());
|
|
|
|
// get the list of the constraints on the table
|
|
m_pTxnConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pTxnConstraints->GetConstraints(NULL, NULL, m_TransactedTable.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
// prepare the constraint
|
|
m_pTransactedTableCons = new CForeignKeyCons();
|
|
|
|
// select column
|
|
TESTC_(m_TransactedTable.GetColInfo(1, col), S_OK);
|
|
((CForeignKeyCons*)m_pTransactedTableCons)->AddForeignKeyColumn(col.GetColID());
|
|
TESTC_(m_ReferencedTable.GetColInfo(1, col), S_OK);
|
|
((CForeignKeyCons*)m_pTransactedTableCons)->AddColumn(col.GetColID());
|
|
((CForeignKeyCons*)m_pTransactedTableCons)->SetReferencedTableID(&m_ReferencedTable.GetTableID());
|
|
|
|
hr = m_pTCITableDefinition->AddConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_TransactedTable.GetTableID(),
|
|
*m_pTransactedTableCons);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //CAddFKConsTxnAdapter::InsideTransactionScope
|
|
|
|
|
|
|
|
HRESULT CAddFKConsTxnAdapter::InsideTransactionOnDDLLock()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
CCol col;
|
|
|
|
CHECK(CAddConstraintTxnAdapter::InsideTransactionOnDDLLock(), S_OK);
|
|
|
|
// create a table and populate it
|
|
TESTC_(pTCITableDefinition()->CreateTableWithNoNullableColumns(&m_TransactedTable, 0, 0), S_OK);
|
|
m_TransactedTable.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_TransactedTable.GetTableName());
|
|
|
|
// select column
|
|
TESTC_(m_TransactedTable.GetColInfo(1, col), S_OK);
|
|
|
|
// get the list of the constraints on the table
|
|
m_pTxnConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pTxnConstraints->GetConstraints(NULL, NULL, m_TransactedTable.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
// prepare the constraint
|
|
m_pTransactedTableCons = new CForeignKeyCons();
|
|
((CForeignKeyCons*)m_pTransactedTableCons)->AddColumn(col.GetColID());
|
|
TESTC_(m_ReferencedTable.GetColInfo(1, col), S_OK);
|
|
((CForeignKeyCons*)m_pTransactedTableCons)->AddForeignKeyColumn(col.GetColID());
|
|
((CForeignKeyCons*)m_pTransactedTableCons)->SetReferencedTableID(&m_ReferencedTable.GetTableID());
|
|
|
|
hr = m_pTCITableDefinition->pITDWC()->AddConstraint(
|
|
&m_TransactedTable.GetTableID(),
|
|
*m_pTransactedTableCons);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //CAddFKConsTxnAdapter::InsideTransactionOnDDLLock
|
|
|
|
|
|
|
|
|
|
BOOL CAddFKConsTxnAdapter::CheckCompletion()
|
|
{
|
|
TBEGIN
|
|
|
|
ASSERT(m_pCons);
|
|
TESTC(CAddConstraintTxnAdapter::CheckCompletion());
|
|
|
|
// check foreign key constraint here
|
|
TESTC_(m_Table.Insert(2), S_OK);
|
|
// there isn't a row with seed 15 in the referenced table
|
|
TESTC_(m_Table.Insert(15), DB_E_INTEGRITYVIOLATION);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddFKConsTxnAdapter::CheckCompletion
|
|
|
|
|
|
|
|
BOOL CAddFKConsTxnAdapter::CheckRollBack()
|
|
{
|
|
TBEGIN
|
|
|
|
ASSERT(m_pCons);
|
|
TESTC(CAddConstraintTxnAdapter::CheckRollBack());
|
|
|
|
// check foreign key constraint here
|
|
TESTC_(m_Table.Insert(2), S_OK);
|
|
TESTC_(m_Table.Insert(15), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddFKConsTxnAdapter::CheckRollBack
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// CAddCheckConsTxnAdapter class
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
BOOL CAddCheckConsTxnAdapter::BeforeTransaction()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
|
|
// create a table and populate it
|
|
TESTC_(m_Table.CreateTable(0, 0), S_OK);
|
|
m_Table.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_Table.GetTableName());
|
|
|
|
// get the list of the constraints on the table
|
|
m_pConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pConstraints->GetConstraints(NULL, NULL, m_Table.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
// select column to be foreign key
|
|
TESTC_(m_Table.GetColInfo(1, col), S_OK);
|
|
|
|
// prepare the constraint
|
|
m_pCons = new CCheckCons();
|
|
// every 3rd row has a negative value
|
|
CHECK(((CCheckCons*)m_pCons)->SetLTCheckConstraint(&m_Table, col.GetColNum(), 6), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddCheckConsTxnAdapter::BeforeTransaction
|
|
|
|
|
|
|
|
HRESULT CAddCheckConsTxnAdapter::InsideTransactionScope()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
CHECK(CAddConstraintTxnAdapter::InsideTransactionScope(), S_OK);
|
|
|
|
// create a table and populate it
|
|
TESTC_(m_TransactedTable.CreateTable(0, 0), S_OK);
|
|
m_Table.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_TransactedTable.GetTableName());
|
|
|
|
// get the list of the constraints on the table
|
|
m_pTxnConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pTxnConstraints->GetConstraints(NULL, NULL, m_TransactedTable.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
// select column to be foreign key
|
|
TESTC_(m_TransactedTable.GetColInfo(1, col), S_OK);
|
|
|
|
// prepare the constraint
|
|
m_pTransactedTableCons = new CCheckCons();
|
|
// every 3rd row has a negative value
|
|
CHECK(((CCheckCons*)m_pTransactedTableCons)->SetLTCheckConstraint(&m_TransactedTable, col.GetColNum(), 6), S_OK);
|
|
|
|
hr = m_pTCITableDefinition->AddConstraintAndCheck(
|
|
m_pTCITableDefinition->pITDWC(),
|
|
&m_TransactedTable.GetTableID(), *m_pTransactedTableCons);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //CAddCheckConsTxnAdapter::InsideTransactionScope
|
|
|
|
|
|
|
|
HRESULT CAddCheckConsTxnAdapter::InsideTransactionOnDDLLock()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
CHECK(CAddConstraintTxnAdapter::InsideTransactionOnDDLLock(), S_OK);
|
|
|
|
// create a table and populate it
|
|
TESTC_(m_TransactedTable.CreateTable(0, 0), S_OK);
|
|
m_TransactedTable.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_TransactedTable.GetTableName());
|
|
|
|
// get the list of the constraints on the table
|
|
m_pTxnConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pTxnConstraints->GetConstraints(NULL, NULL, m_TransactedTable.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
// select column to be foreign key
|
|
TESTC_(m_TransactedTable.GetColInfo(1, col), S_OK);
|
|
|
|
// prepare the constraint
|
|
m_pTransactedTableCons = new CCheckCons();
|
|
// every 3rd row has a negative value
|
|
CHECK(((CCheckCons*)m_pTransactedTableCons)->SetLTCheckConstraint(&m_TransactedTable, col.GetColNum(), 6), S_OK);
|
|
|
|
hr = m_pTCITableDefinition->pITDWC()->AddConstraint(
|
|
&m_TransactedTable.GetTableID(), *m_pTransactedTableCons);
|
|
CLEANUP:
|
|
return hr;
|
|
} //CAddCheckConsTxnAdapter::InsideTransactionOnDDLLock
|
|
|
|
|
|
|
|
BOOL CAddCheckConsTxnAdapter::CheckCompletion()
|
|
{
|
|
TBEGIN
|
|
|
|
ASSERT(m_pCons);
|
|
TESTC(CAddConstraintTxnAdapter::CheckCompletion());
|
|
|
|
// check foreign key constraint here
|
|
TESTC_(m_Table.Insert(4), S_OK);
|
|
TESTC_(m_Table.Insert(8), DB_E_INTEGRITYVIOLATION);
|
|
|
|
TESTC_(m_TransactedTable.Insert(4), S_OK);
|
|
TESTC_(m_TransactedTable.Insert(8), DB_E_INTEGRITYVIOLATION);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddCheckConsTxnAdapter::CheckCompletion
|
|
|
|
|
|
|
|
BOOL CAddCheckConsTxnAdapter::CheckRollBack()
|
|
{
|
|
TBEGIN
|
|
|
|
ASSERT(m_pCons);
|
|
TESTC(CAddConstraintTxnAdapter::CheckRollBack());
|
|
|
|
// check constraint here
|
|
TESTC_(m_Table.Insert(4), S_OK);
|
|
TESTC_(m_Table.Insert(8), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CAddCheckConsTxnAdapter::CheckRollBack
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
//
|
|
// class CCreateTableWithConsTxnAdapter
|
|
//
|
|
////////////////////////////////////////////////////////
|
|
BOOL CCreateTableWithConsTxnAdapter::BeforeTransaction()
|
|
{
|
|
TBEGIN
|
|
CUniqueCons consUnique;
|
|
CPrimaryKeyCons consPrimaryKey;
|
|
CForeignKeyCons consForeignKey(NULL, m_pTCITableDefinition->SupportedMatchType());
|
|
DBORDINAL rgReferencedCol[] = {1};
|
|
CCol col;
|
|
CList <WCHAR*, WCHAR*> ListNativeTemp;
|
|
CList <DBTYPE, DBTYPE> ListDataTypes;
|
|
CList <CCol, CCol&> ColList;
|
|
|
|
// create table name
|
|
m_Table.MakeTableName(NULL);
|
|
|
|
// get the provider types list
|
|
// all types appear in CreateColList, so I don't have to use CreateTypeColInfo
|
|
m_Table.CreateTypeColInfo(ListNativeTemp, ListDataTypes, ALLTYPES);
|
|
m_Table.DuplicateColList(ColList);
|
|
|
|
// in m_rgColumnDesc I would rather load just the types prepared for table creation
|
|
m_Table.CreateColInfo(ListNativeTemp, ListDataTypes, ALLTYPES);
|
|
// build the column description array
|
|
m_Table.BuildColumnDescs(&m_rgColumnDesc);
|
|
m_cColumnDesc = m_Table.CountColumnsOnTable();
|
|
m_Table.SetBuildColumnDesc(FALSE);
|
|
|
|
// release the properties on all column and make the first column not nullable
|
|
ReleaseAllColumnPropSets(m_rgColumnDesc, m_cColumnDesc);
|
|
m_pTCITableDefinition->SetProperty(&m_rgColumnDesc[0].rgPropertySets, &m_rgColumnDesc[0].cPropertySets,
|
|
DBPROP_COL_NULLABLE,
|
|
VT_BOOL, (LPVOID)VARIANT_FALSE,
|
|
DBPROPOPTIONS_REQUIRED);
|
|
|
|
// create support for foreign key constraint
|
|
TESTC_(m_RefTable.CreateTable(0, 0), S_OK);
|
|
m_RefTable.AddInfoFromColumnsSchemaRowset(m_pTCITableDefinition->pITDWC(), m_RefTable.GetTableName());
|
|
|
|
// make the referenced columns unique
|
|
TESTC_(m_pTCITableDefinition->AddUniqueConstraint(&m_RefTable, rgReferencedCol[0], (DBDEFERRABILITY)0), S_OK);
|
|
|
|
// set a unique constraint on the second column
|
|
consUnique.AddColumn(&m_rgColumnDesc[1].dbcid);
|
|
|
|
// set a primary key on the first column of the table
|
|
consPrimaryKey.AddColumn(&m_rgColumnDesc[0].dbcid);
|
|
|
|
// set a simple foreign key constraint
|
|
TESTC_(m_RefTable.GetColInfo(1, col), S_OK);
|
|
consForeignKey.AddColumn(col.GetColID());
|
|
consForeignKey.AddForeignKeyColumn(&m_rgColumnDesc[0].dbcid);
|
|
consForeignKey.SetReferencedTableID(&m_RefTable.GetTableID());
|
|
|
|
// add all constraint to the array
|
|
m_ConsDescArray.AddConsDesc(consUnique);
|
|
m_ConsDescArray.AddConsDesc(consForeignKey);
|
|
m_ConsDescArray.AddConsDesc(consPrimaryKey);
|
|
|
|
// get the list of the constraints on the table
|
|
m_pConstraints = new CConstraints(g_pIOpenRowset);
|
|
TESTC_(m_pConstraints->GetConstraints(NULL, NULL, m_Table.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CCreateTableWithConsTxnAdapter::BeforeTransaction
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
//
|
|
// class CDropConsTxnAdapter
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
BOOL CDropConsTxnAdapter::BeforeTransaction()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
|
|
TESTC_(pTCITableDefinition()->CreateTableWithNoNullableColumns(&m_Table, 0, 0), S_OK);
|
|
m_Table.AddInfoFromColumnsSchemaRowset(m_pTCITableDefinition->pITDWC(), m_Table.GetTableName());
|
|
|
|
TESTC_(pTCITableDefinition()->CreateTableWithNoNullableColumns(&m_RefTable, 0, 0), S_OK);
|
|
m_RefTable.AddInfoFromColumnsSchemaRowset(m_pTCITableDefinition->pITDWC(), m_RefTable.GetTableName());
|
|
TESTC_(m_pTCITableDefinition->AddUniqueConstraint(&m_RefTable, 1), S_OK);
|
|
|
|
// choose 1 column and create a unique constraint on them
|
|
TESTC_(m_Table.GetColInfo(1, col), S_OK);
|
|
m_pFKCons = new CForeignKeyCons(NULL, m_pTCITableDefinition->SupportedMatchType());
|
|
m_pFKCons->AddForeignKeyColumn(col.GetColID());
|
|
|
|
TESTC_(m_RefTable.GetColInfo(1, col), S_OK);
|
|
m_pFKCons->AddColumn(col.GetColID());
|
|
|
|
m_pFKCons->SetReferencedTableID(&m_RefTable.GetTableID());
|
|
|
|
CHECK(m_pTCITableDefinition->AddConstraintAndCheck(m_pTCITableDefinition->pITDWC(), &m_Table.GetTableID(), *m_pFKCons), S_OK);
|
|
|
|
// Add constraint
|
|
m_pPKCons = new CPrimaryKeyCons();
|
|
m_pPKCons->AddColumn(col.GetColID());
|
|
CHECK(m_pTCITableDefinition->AddConstraintAndCheck(m_pTCITableDefinition->pITDWC(), &m_Table.GetTableID(), *m_pPKCons), S_OK);
|
|
|
|
// Add constraint
|
|
m_pUniqueCons = new CUniqueCons();
|
|
m_pUniqueCons->AddColumn(col.GetColID());
|
|
CHECK(m_pTCITableDefinition->AddConstraintAndCheck(m_pTCITableDefinition->pITDWC(), &m_Table.GetTableID(), *m_pUniqueCons), S_OK);
|
|
|
|
// Add constraint
|
|
m_pCheckCons = new CCheckCons();
|
|
m_pCheckCons->SetLTCheckConstraint(&m_Table, col.GetColNum(), 5);
|
|
CHECK(m_pTCITableDefinition->AddConstraintAndCheck(m_pTCITableDefinition->pITDWC(), &m_Table.GetTableID(), *m_pCheckCons), S_OK);
|
|
|
|
// get the list of the constraints on the table
|
|
m_pConstraints = new CConstraints(g_pIOpenRowset);
|
|
CHECK(m_pConstraints->GetConstraints(NULL, NULL, m_Table.GetTableName(), NULL, NULL, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
} //CDropConsTxnAdapter::BeforeTransaction
|
|
|
|
|
|
|
|
|
|
HRESULT CTransactionLocal::StartTransaction(
|
|
IUnknown *pISessionUnknown,
|
|
// arguments for ITransactionLocal::StartTransaction
|
|
ISOLEVEL isoLevel,
|
|
ULONG isoFlags,
|
|
ITransactionOptions *pOtherOptions
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
CPropSets PropSets;
|
|
DBPROP *pSupportedTxnDDL;
|
|
|
|
m_lSupportedTxnDDL = DBPROPVAL_TC_NONE;
|
|
|
|
if (!pISessionUnknown)
|
|
return E_INVALIDARG;
|
|
|
|
m_Session = pISessionUnknown;
|
|
|
|
TESTC_(m_Session.GetDataSource(m_DataSource), S_OK);
|
|
|
|
// get DBPROP_SUPPORTEDTXNDDL
|
|
TESTC_(m_DataSource.GetProperties(&PropSets), S_OK);
|
|
pSupportedTxnDDL = PropSets.FindProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO);
|
|
|
|
TESTC(!pSupportedTxnDDL || (VT_I4 == pSupportedTxnDDL->vValue.vt));
|
|
if (pSupportedTxnDDL)
|
|
m_lSupportedTxnDDL = V_I4(&pSupportedTxnDDL->vValue);
|
|
else if ((ITransactionLocal*)m_Session)
|
|
m_lSupportedTxnDDL = DBPROPVAL_TC_ALL;
|
|
|
|
// check the relation between the property and the interface
|
|
TESTC( (NULL != (ITransactionLocal*)m_Session)
|
|
|| (!pSupportedTxnDDL || (DBPROPVAL_TC_NONE == m_lSupportedTxnDDL)));
|
|
|
|
// if the interface is not supported just return
|
|
if (NULL == (ITransactionLocal*)m_Session)
|
|
return S_OK;
|
|
|
|
hr = ((ITransactionLocal*)m_Session)->StartTransaction(isoLevel, isoFlags, pOtherOptions, NULL);
|
|
|
|
if (hr==S_OK)
|
|
// Set the flag that we're inside transaction
|
|
CConsDesc::s_fInsideTransaction = TRUE;
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
} //CTransactionLocal::StartTransaction
|
|
|
|
|
|
|
|
BOOL CTransactionLocal::DoTransactionTest(
|
|
IUnknown *pISessionUnknown,
|
|
CTransactionAdapter *pTAdapter,
|
|
// arguments for ITransactionLocal::Abort / Commit
|
|
BOOL fDDL, // whether or not this is a DDL call
|
|
BOOL fAbortCommit, // whether to abort or commit
|
|
BOOL fRetaining // if it's retaining or not
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
ULONG cIsoLevel, i;
|
|
ISOLEVEL rgIsoLevel[] = {ISOLATIONLEVEL_BROWSE, ISOLATIONLEVEL_CURSORSTABILITY,
|
|
ISOLATIONLEVEL_ISOLATED, ISOLATIONLEVEL_CHAOS};
|
|
cIsoLevel = NUMELEM(rgIsoLevel);
|
|
|
|
TESTC(NULL != pISessionUnknown);
|
|
TESTC(NULL != pTAdapter);
|
|
|
|
m_pTAdapter = pTAdapter;
|
|
|
|
// do work / testing that precedes transaction
|
|
COMPARE(m_pTAdapter->BeforeTransaction(), TRUE);
|
|
|
|
// start the transaction
|
|
for (i=0; i<cIsoLevel; i++)
|
|
{
|
|
if (S_OK == (hr = StartTransaction(pISessionUnknown, rgIsoLevel[i], 0, NULL)))
|
|
break;
|
|
}
|
|
if (cIsoLevel < i)
|
|
return E_FAIL;
|
|
|
|
// TESTC_(m_pTAdapter->pTCITableDefinition()->StartTransaction(), S_OK);
|
|
// TESTC_(StartTransaction(pISessionUnknown, isoLevel, isoFlags, pOtherOptions), S_OK);
|
|
|
|
// check that we have a local transaction; return if not
|
|
TESTC_PROVIDER(NULL != (ITransactionLocal*)m_Session);
|
|
|
|
if (!fDDL)
|
|
{ TESTC_(m_pTAdapter->InsideTransactionScope(), S_OK);}
|
|
else
|
|
{
|
|
switch (m_lSupportedTxnDDL)
|
|
{
|
|
case DBPROPVAL_TC_DML:
|
|
//check for XACT_E_XTIONEXISTS
|
|
CHECK(hr = m_pTAdapter->InsideTransactionScope(), XACT_E_XTIONEXISTS);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_IGNORE:
|
|
// the statement is not transacted
|
|
case DBPROPVAL_TC_ALL:
|
|
case DBPROPVAL_TC_DDL_COMMIT:
|
|
CHECK(hr = m_pTAdapter->InsideTransactionScope(), S_OK);
|
|
break;
|
|
|
|
case DBPROPVAL_TC_DDL_LOCK:
|
|
CHECK(hr = m_pTAdapter->InsideTransactionOnDDLLock(), S_OK);
|
|
break;
|
|
|
|
default:
|
|
TESTC(FALSE);
|
|
}
|
|
}
|
|
|
|
// end transaction
|
|
if (!fDDL || (DBPROPVAL_TC_DDL_COMMIT != m_lSupportedTxnDDL))
|
|
{
|
|
if (fAbortCommit)
|
|
{
|
|
CHECK(Abort(NULL, fRetaining, FALSE), S_OK);
|
|
}
|
|
else
|
|
{
|
|
CHECK(Commit(fRetaining, 0, 0), S_OK);
|
|
}
|
|
}
|
|
|
|
// check the result of the operation
|
|
if (
|
|
// DDL and aborted but prop is DDL ignore or DDL commit
|
|
( fDDL
|
|
&& ( (DBPROPVAL_TC_DDL_COMMIT == m_lSupportedTxnDDL)
|
|
|| (DBPROPVAL_TC_DDL_IGNORE == m_lSupportedTxnDDL))
|
|
//&& fAbortCommit // this is not necessary
|
|
)
|
|
// DDL and committed but prop is DML
|
|
|| ( fDDL
|
|
&& (DBPROPVAL_TC_DML == m_lSupportedTxnDDL)
|
|
//&& !fAbortCommit // this is not necessary
|
|
)
|
|
// operation is not a DDL and txn is committed
|
|
|| !fAbortCommit)
|
|
COMPARE(m_pTAdapter->CheckCompletion(), TRUE);
|
|
else
|
|
COMPARE(m_pTAdapter->CheckRollBack(), TRUE);
|
|
|
|
// end this transaction
|
|
CHECK(Commit(FALSE, 0, 0), fRetaining? S_OK: XACT_E_NOTRANSACTION);
|
|
CHECK(Abort(NULL, FALSE, FALSE), XACT_E_NOTRANSACTION);
|
|
|
|
CLEANUP:
|
|
CConsDesc::s_fInsideTransaction = FALSE;
|
|
TRETURN
|
|
} //CTransactionLocal::DoTransactionTest
|
|
|
|
|
|
|
|
|
|
|