7868 lines
202 KiB
C++
7868 lines
202 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright (C) 1995-2000 Microsoft Corporation
|
|
//
|
|
// @doc
|
|
//
|
|
// @module IALTERTABLE.CPP | IALTERTABLE source file for all test modules.
|
|
//
|
|
|
|
#include "MODStandard.hpp" // Standard headers
|
|
#include "IAlterTable.h" // IAlterTable header
|
|
#include "ExtraLib.h"
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Module Values
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// {{ TCW_MODULE_GLOBALS
|
|
DECLARE_MODULE_CLSID = { 0xe81d1260, 0x4c52, 0x11d3, { 0xaf, 0x74, 0x00, 0xc0, 0x4f, 0x78, 0x29, 0x26} };
|
|
DECLARE_MODULE_NAME("IAlterTable");
|
|
DECLARE_MODULE_OWNER("Microsoft");
|
|
DECLARE_MODULE_DESCRIP("IAlterTable Interface Test");
|
|
DECLARE_MODULE_VERSION(795921705);
|
|
// TCW_WizardVersion(2)
|
|
// TCW_Automation(True)
|
|
// }} TCW_MODULE_GLOBALS_END
|
|
|
|
// Limit new column length to 200
|
|
#define NEWCOLUMNLEN 200
|
|
|
|
// Classification of DataTypes
|
|
enum ETYPECLASS
|
|
{
|
|
CLASS_SIGNEDINT, // signed integer
|
|
CLASS_UNSIGNEDINT, // unsigned integer
|
|
CLASS_APPROXNUM, // approximate numeric e.g. float, real
|
|
CLASS_SCALEDINT, // scaled exact integer
|
|
CLASS_DATE, // date type
|
|
CLASS_STRING, // string
|
|
CLASS_SPECIAL, // no like type e.g. uniqueidentifier, variant
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
class TCIAlterTable : public CSessionObject
|
|
{
|
|
public:
|
|
//constructors
|
|
TCIAlterTable(WCHAR* pwszTestCaseName = INVALID(WCHAR*));
|
|
virtual ~TCIAlterTable();
|
|
|
|
//methods
|
|
virtual BOOL Init();
|
|
virtual BOOL Terminate();
|
|
|
|
virtual HRESULT AlterTable
|
|
(
|
|
DBID * pTableID,
|
|
DBID * pNewTableID,
|
|
ULONG cPropertySets = 0,
|
|
DBPROPSET * rgPropertySets = NULL
|
|
);
|
|
|
|
virtual HRESULT AlterColumn
|
|
(
|
|
DBID * pTableID = NULL,
|
|
DBID * pColumnID = NULL,
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags = 0,
|
|
DBCOLUMNDESC * pColumnDesc = NULL
|
|
);
|
|
|
|
virtual BOOL SetProperty
|
|
(
|
|
DBPROPID dwPropertyID,
|
|
GUID guidPropertySet = DBPROPSET_TABLE,
|
|
void * pValue = (void *)VARIANT_TRUE,
|
|
DBTYPE wType = DBTYPE_BOOL,
|
|
DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED,
|
|
DBID colid = DB_NULLID
|
|
);
|
|
|
|
virtual BOOL CheckUnsupportedProp
|
|
(
|
|
ULONG cPropSets,
|
|
DBPROPSET * rgPropSets
|
|
);
|
|
|
|
virtual BOOL VerifyPropStatus
|
|
(
|
|
ULONG cPropSets,
|
|
DBPROPSET * rgPropSets,
|
|
DBPROPID dwPropertyID,
|
|
GUID guidPropertySet,
|
|
DBPROPSTATUS dwInputStatus
|
|
);
|
|
|
|
virtual BOOL VerifyAlterTable
|
|
(
|
|
DBID * pTableID,
|
|
DBID * pNewTableID
|
|
);
|
|
|
|
virtual BOOL CheckAlterTableID
|
|
(
|
|
DBID * pTableID,
|
|
DBID * pNewTableID
|
|
);
|
|
|
|
virtual BOOL VerifyAlterTableProperties
|
|
(
|
|
DBID * pTableID,
|
|
DBPROPID dbPropID,
|
|
GUID guidPropertySet,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions
|
|
);
|
|
|
|
virtual BOOL VerifyAlterInvalidTableProperties
|
|
(
|
|
DBID * pTableID,
|
|
DBPROPSTATUS dwExpectedStatus,
|
|
DBPROPID dbPropID,
|
|
GUID guidPropertySet,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions,
|
|
DBID colid = DB_NULLID
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumn
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags,
|
|
DBCOLUMNDESC * pColumnDesc,
|
|
CTable * pTable = NULL,
|
|
HRESULT * phr = NULL
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumnName
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBID * pNewColumnID
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumnSize
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBLENGTH ulNewColSize,
|
|
CTable * pTable = NULL
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumnPrecision
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
BYTE bNewPrecision
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumnScale
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
BYTE bNewScale
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumnCLSID
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
CLSID * pclsid
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumnType
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBTYPE wType,
|
|
CTable * pTable
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumnTypeName
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
WCHAR * pwszTypeName,
|
|
CTable * pTable
|
|
);
|
|
|
|
virtual BOOL VerifyAlterColumnProperty
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBPROPID dbPropID,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED
|
|
);
|
|
|
|
|
|
virtual BOOL VerifyAlterInvalidColumnProperties
|
|
(
|
|
CTable * pTable,
|
|
DBPROPSTATUS dwExpectedStatus,
|
|
DBPROPID dbPropID,
|
|
GUID guidPropertySet,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions,
|
|
DBID colid = DB_NULLID
|
|
);
|
|
|
|
virtual BOOL CompareColumnMetaData
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags,
|
|
DBCOLUMNDESC * pColumnDesc,
|
|
CTable * pTable = NULL
|
|
);
|
|
|
|
virtual BOOL CacheLiteralInfo();
|
|
|
|
virtual HRESULT MakeNewID
|
|
(
|
|
DBID * pDBID,
|
|
DBKINDENUM eKind,
|
|
size_t ulLen
|
|
);
|
|
|
|
virtual HRESULT MakeNewTableID
|
|
(
|
|
DBID * pDBID,
|
|
DBKINDENUM eKind,
|
|
size_t ulLen
|
|
);
|
|
|
|
virtual HRESULT MakeNewColumnID
|
|
(
|
|
DBID * pNewColumnID,
|
|
DBKINDENUM eKind,
|
|
size_t ulLen
|
|
);
|
|
|
|
virtual BOOL RestoreTableID
|
|
(
|
|
DBID * pCurrentID
|
|
);
|
|
|
|
virtual BOOL RestoreColumnID
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBID * pCurrentID,
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags
|
|
);
|
|
|
|
virtual HRESULT CreateTable
|
|
(
|
|
CTable ** ppTable
|
|
);
|
|
|
|
virtual HRESULT CreateTable
|
|
(
|
|
CTable ** ppTable,
|
|
DBPROPID dbPropID,
|
|
void * pValue,
|
|
DBPROPOPTIONS dwOptions
|
|
);
|
|
|
|
virtual HRESULT CreateOneColTableWithProps
|
|
(
|
|
CTable ** ppTable,
|
|
CCol * pCol,
|
|
ULONG cPropSets,
|
|
DBPROPSET * rgPropSets
|
|
);
|
|
|
|
virtual BOOL VerifyNonTableProps
|
|
(
|
|
DBPROPOPTIONS dwOptions
|
|
);
|
|
|
|
virtual HRESULT SetChangeColInfo
|
|
(
|
|
CCol * pCol
|
|
);
|
|
|
|
virtual BOOL GetReadOnlySession
|
|
(
|
|
IUnknown ** ppUnkReadSession
|
|
);
|
|
|
|
virtual BOOL AlterPropertyAndVerifyRowset
|
|
(
|
|
DBPROPID dbPropID
|
|
);
|
|
|
|
virtual BOOL VerifyRowsetValues
|
|
(
|
|
CTable * pTable,
|
|
DBPROPID dbPropID
|
|
);
|
|
|
|
virtual BOOL UpgradeType
|
|
(
|
|
CCol * pCurrentCol,
|
|
CCol * pNewCol,
|
|
BOOL fAllowLong = FALSE
|
|
);
|
|
|
|
virtual BOOL IsTypeGreater
|
|
(
|
|
CCol * pCurCol,
|
|
CCol * pNewCol
|
|
);
|
|
|
|
virtual ULONG GetTypeClass
|
|
(
|
|
DBTYPE wType
|
|
);
|
|
|
|
virtual ULONG GetTypeRank
|
|
(
|
|
DBTYPE wType
|
|
);
|
|
|
|
virtual BOOL MakeDefaultData
|
|
(
|
|
CCol * pCol,
|
|
void ** ppData,
|
|
DBTYPE * pwType,
|
|
CTable * pTable
|
|
);
|
|
|
|
void ReleaseDefaultData
|
|
(
|
|
void * pDefaultData,
|
|
DBTYPE wDefaultType
|
|
);
|
|
|
|
virtual BOOL VerifyTableDefault
|
|
(
|
|
CTable * pTable,
|
|
BOOL fDefaultExists
|
|
);
|
|
|
|
virtual BOOL VerifyTableUnique
|
|
(
|
|
CTable * pTable,
|
|
BOOL fUniqueExists
|
|
);
|
|
|
|
virtual BOOL AlterStringCol2BLOB
|
|
(
|
|
DBTYPE wTargetType,
|
|
BOOL fIsFixed
|
|
);
|
|
|
|
virtual BOOL TCAlterCompareDBID
|
|
(
|
|
DBID * pdbid1,
|
|
DBID * pdbid2
|
|
);
|
|
|
|
static ULONG WINAPI Thread_AlterTable(void* pv);
|
|
|
|
static ULONG WINAPI Thread_AlterColumn(void* pv);
|
|
|
|
//Data
|
|
IAlterTable * m_pIAlterTable;
|
|
|
|
CTable * m_pSchema;
|
|
CSchema * m_pFullSchemaInfo;
|
|
CCol m_Col;
|
|
|
|
ULONG m_cchMaxTableName;
|
|
ULONG m_cchMaxColName;
|
|
WCHAR * m_pwszInvalidTableChars;
|
|
WCHAR * m_pwszInvalidStartingTableChars;
|
|
WCHAR * m_pwszInvalidColChars;
|
|
WCHAR * m_pwszInvalidStartingColChars;
|
|
|
|
DBKINDENUM m_lDBIDType;
|
|
|
|
DBCOLUMNDESCFLAGS m_lAlterColumnSupport;
|
|
|
|
DBID m_TableID;
|
|
DBID m_ColumnID;
|
|
|
|
CCol * m_pChangedCol;
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::TCIAlterTable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
TCIAlterTable::TCIAlterTable(WCHAR * wstrTestCaseName) : CSessionObject(wstrTestCaseName)
|
|
{
|
|
m_pIAlterTable = NULL;
|
|
m_pSchema = NULL;
|
|
m_pFullSchemaInfo = NULL;
|
|
|
|
m_cchMaxTableName = ~0;
|
|
m_cchMaxColName = ~0;
|
|
|
|
m_pwszInvalidTableChars = NULL;
|
|
m_pwszInvalidStartingTableChars = NULL;
|
|
m_pwszInvalidColChars = NULL;
|
|
m_pwszInvalidStartingColChars = NULL;
|
|
|
|
m_lDBIDType = DBKIND_NAME;
|
|
|
|
m_lAlterColumnSupport = 0;
|
|
|
|
memset(&m_TableID, 0, sizeof(DBID));
|
|
memset(&m_ColumnID, 0, sizeof(DBID));
|
|
|
|
m_pChangedCol = NULL;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::~TCIAlterTable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
TCIAlterTable::~TCIAlterTable()
|
|
{
|
|
ReleaseDBID(&m_TableID, FALSE);
|
|
ReleaseDBID(&m_ColumnID, FALSE);
|
|
|
|
SAFE_FREE(m_pwszInvalidTableChars);
|
|
SAFE_FREE(m_pwszInvalidStartingTableChars);
|
|
SAFE_FREE(m_pwszInvalidColChars);
|
|
SAFE_FREE(m_pwszInvalidStartingColChars);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::Init
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::Init()
|
|
{
|
|
BOOL fPass = TEST_FAIL;
|
|
LONG_PTR lSQLSupport = 0;
|
|
|
|
//Init baseclass
|
|
TESTC(CSessionObject::Init())
|
|
|
|
//Use the global DSO created in Module init
|
|
SetDataSourceObject(g_pIDBInitialize);
|
|
|
|
//Use the global DB Rowset created in Module init
|
|
SetDBSession(g_pIOpenRowset);
|
|
|
|
m_pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(m_pTable != NULL)
|
|
TESTC_(m_pTable->CreateTable(0,COL_ONE,NULL,PRIMARY,TRUE),S_OK);
|
|
|
|
TESTC_(DuplicateDBID(m_pTable->GetTableID(), &m_TableID), S_OK);
|
|
m_lDBIDType = (DBKINDENUM)m_TableID.eKind;
|
|
|
|
TESTC(CacheLiteralInfo());
|
|
|
|
TESTC(VerifyInterface(m_pIOpenRowset, IID_IAlterTable, SESSION_INTERFACE,
|
|
(IUnknown**)&m_pIAlterTable));
|
|
|
|
m_pFullSchemaInfo = new CSchema();
|
|
TESTC(m_pFullSchemaInfo != NULL);
|
|
|
|
GetProperty(DBPROP_SQLSUPPORT, DBPROPSET_DATASOURCEINFO,
|
|
m_pIDBInitialize, (ULONG_PTR *)&lSQLSupport);
|
|
|
|
TESTC(SUCCEEDED(m_pFullSchemaInfo->PopulateTypeInfo(m_pIOpenRowset,
|
|
lSQLSupport)));
|
|
|
|
fPass = TEST_PASS;
|
|
|
|
CLEANUP:
|
|
|
|
return fPass;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::Terminate
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::Terminate()
|
|
{
|
|
if( m_pTable )
|
|
{
|
|
m_pTable->DropTable();
|
|
SAFE_DELETE(m_pTable);
|
|
}
|
|
|
|
SAFE_DELETE(m_pFullSchemaInfo);
|
|
|
|
SAFE_RELEASE(m_pIAlterTable);
|
|
|
|
SAFE_FREE(m_pwszInvalidTableChars);
|
|
SAFE_FREE(m_pwszInvalidStartingTableChars);
|
|
SAFE_FREE(m_pwszInvalidColChars);
|
|
SAFE_FREE(m_pwszInvalidStartingColChars);
|
|
|
|
ReleaseDBSession();
|
|
ReleaseDataSourceObject();
|
|
|
|
return CSessionObject::Terminate();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::CacheLiteralInfo
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::CacheLiteralInfo()
|
|
{
|
|
BOOL fSuccess = FALSE;
|
|
IDBInfo * pIDBInfo = NULL;
|
|
DBLITERAL rgDBLiterals[] = {DBLITERAL_TABLE_NAME, DBLITERAL_COLUMN_NAME};
|
|
ULONG cLiteralInfo = 0;
|
|
DBLITERALINFO * rgLiteralInfo = NULL;
|
|
WCHAR * pCharBuffer = NULL;
|
|
DWORDLONG dwl = 0;
|
|
|
|
|
|
TESTC(GetProperty(DBPROP_ALTERCOLUMN, DBPROPSET_DATASOURCEINFO,
|
|
m_pIDBInitialize, (ULONG_PTR *)&dwl));
|
|
m_lAlterColumnSupport = (DBCOLUMNDESCFLAGS)dwl;
|
|
|
|
if(VerifyInterface(m_pIDBInitialize, IID_IDBInfo, DATASOURCE_INTERFACE,
|
|
(IUnknown **)&pIDBInfo))
|
|
{
|
|
TESTC_(pIDBInfo->GetLiteralInfo(NUMELEM(rgDBLiterals), rgDBLiterals,
|
|
&cLiteralInfo, &rgLiteralInfo, &pCharBuffer), S_OK);
|
|
TESTC(cLiteralInfo == 2);
|
|
|
|
if( rgLiteralInfo[0].fSupported )
|
|
{
|
|
m_cchMaxTableName = rgLiteralInfo[0].cchMaxLen;
|
|
m_pwszInvalidTableChars = wcsDuplicate(rgLiteralInfo[0].pwszInvalidChars);
|
|
m_pwszInvalidStartingTableChars = wcsDuplicate(rgLiteralInfo[0].pwszInvalidStartingChars);
|
|
}
|
|
|
|
if( rgLiteralInfo[1].fSupported )
|
|
{
|
|
m_cchMaxColName = rgLiteralInfo[1].cchMaxLen;
|
|
m_pwszInvalidColChars = wcsDuplicate(rgLiteralInfo[1].pwszInvalidChars);
|
|
m_pwszInvalidStartingColChars = wcsDuplicate(rgLiteralInfo[1].pwszInvalidStartingChars);
|
|
}
|
|
}
|
|
|
|
fSuccess = TRUE;
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_FREE(pCharBuffer);
|
|
SAFE_FREE(rgLiteralInfo);
|
|
|
|
SAFE_RELEASE(pIDBInfo);
|
|
|
|
return fSuccess;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::AlterTable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::AlterTable
|
|
(
|
|
DBID * pTableID,
|
|
DBID * pNewTableID,
|
|
ULONG cPropertySets,
|
|
DBPROPSET * rgPropertySets
|
|
)
|
|
{
|
|
return m_pIAlterTable->AlterTable(pTableID, pNewTableID, cPropertySets, rgPropertySets);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::AlterColumn
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::AlterColumn
|
|
(
|
|
DBID * pTableID,
|
|
DBID * pColumnID,
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags,
|
|
DBCOLUMNDESC * pColumnDesc
|
|
|
|
)
|
|
{
|
|
return m_pIAlterTable->AlterColumn(pTableID, pColumnID, ColumnDescFlags, pColumnDesc);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::SetProperty
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::SetProperty
|
|
(
|
|
DBPROPID dwPropertyID,
|
|
GUID guidPropertySet,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions,
|
|
DBID colid
|
|
)
|
|
{
|
|
return ::SetProperty(dwPropertyID, guidPropertySet, &m_cPropSets,
|
|
&m_rgPropSets, pValue, wType, dwOptions, colid);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::CheckUnsupportedProp
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::CheckUnsupportedProp
|
|
(
|
|
ULONG cPropSets,
|
|
DBPROPSET * rgPropSets
|
|
)
|
|
{
|
|
TBEGIN
|
|
|
|
for(ULONG iPropSet=0; iPropSet<cPropSets && rgPropSets; iPropSet++)
|
|
{
|
|
DBPROPSET * pPropSet = &rgPropSets[iPropSet];
|
|
|
|
//Loop over all the properties of this set
|
|
for(ULONG iProp=0; iProp<pPropSet->cProperties && pPropSet->rgProperties; iProp++)
|
|
{
|
|
DBPROP * pProp = &pPropSet->rgProperties[iProp];
|
|
|
|
if( pProp->dwStatus != DBPROPSTATUS_OK )
|
|
{
|
|
if( pProp->dwOptions == DBPROPOPTIONS_OPTIONAL )
|
|
{
|
|
COMPARE(pProp->dwStatus, DBPROPSTATUS_NOTSET);
|
|
}
|
|
else
|
|
{
|
|
// This method should only be called with valid parameters
|
|
// Hence, it should only fail if a property is not supported.
|
|
TESTC(pProp->dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyPropStatus
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyPropStatus
|
|
(
|
|
ULONG cPropSets,
|
|
DBPROPSET * rgPropSets,
|
|
DBPROPID dwPropertyID,
|
|
GUID guidPropertySet,
|
|
DBPROPSTATUS dwInputStatus
|
|
)
|
|
{
|
|
ASSERT(cPropSets && rgPropSets);
|
|
TBEGIN
|
|
DBPROP * pProp = NULL;
|
|
|
|
//Need to find the property within the PropSets
|
|
DBPROPFLAGS dwFlags = GetPropInfoFlags(dwPropertyID, guidPropertySet);
|
|
TESTC(FindProperty(dwPropertyID, guidPropertySet, cPropSets, rgPropSets, &pProp))
|
|
|
|
// Check for UNSUPPORTED property
|
|
if(pProp->dwStatus == DBPROPSTATUS_NOTSUPPORTED)
|
|
{
|
|
TOUTPUT("Status returned: " << GetPropStatusName(pProp->dwStatus) << " For property: " << GetPropertyName(pProp->dwPropertyID, guidPropertySet));
|
|
goto CLEANUP;
|
|
}
|
|
|
|
// Otherwise delegate to Extralib's VerifyPropStatus
|
|
TESTC(::VerifyPropStatus(cPropSets, rgPropSets, dwPropertyID, guidPropertySet, dwInputStatus));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterTable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterTable
|
|
(
|
|
DBID * pTableID,
|
|
DBID * pNewTableID
|
|
)
|
|
{
|
|
TBEGIN
|
|
|
|
TESTC( SUCCEEDED(AlterTable(pTableID, pNewTableID)) );
|
|
|
|
TESTC(CheckAlterTableID(pTableID, pNewTableID));
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::CheckAlterTableID
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::CheckAlterTableID
|
|
(
|
|
DBID * pTableID,
|
|
DBID * pNewTableID
|
|
)
|
|
{
|
|
TBEGIN
|
|
BOOL fExists;
|
|
|
|
// pNewTableID is NULL or pNewTableID is the same as pTableID,
|
|
// then the table ID should not have changed
|
|
if( !pNewTableID || CompareDBID(*pTableID, *pNewTableID) )
|
|
{
|
|
TESTC_(m_pTable->DoesTableExist(pTableID, &fExists), S_OK);
|
|
TESTC(fExists == TRUE);
|
|
}
|
|
else
|
|
{
|
|
|
|
TESTC_(m_pTable->DoesTableExist(pTableID, &fExists), S_OK);
|
|
TESTC(fExists == FALSE);
|
|
|
|
TESTC_(m_pTable->DoesTableExist(pNewTableID, &fExists), S_OK);
|
|
TESTC(fExists == TRUE);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterTableProperties
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterTableProperties
|
|
(
|
|
DBID * pTableID,
|
|
DBPROPID dbPropID,
|
|
GUID guidPropertySet,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET * rgPropSets = NULL;
|
|
BOOL fSupported;
|
|
BOOL fSettable;
|
|
DBPROP * pProp = NULL;
|
|
|
|
fSupported = SupportedProperty(dbPropID, DBPROPSET_TABLE);
|
|
fSettable = SettableProperty(dbPropID, DBPROPSET_TABLE);
|
|
|
|
::SetProperty(dbPropID, guidPropertySet, &cPropSets, &rgPropSets,
|
|
pValue, wType, dwOptions);
|
|
|
|
pProp = rgPropSets[0].rgProperties;
|
|
|
|
hr = AlterTable(pTableID, NULL, cPropSets, rgPropSets);
|
|
|
|
if( hr == DB_E_ERRORSOCCURRED && pProp->dwStatus == DBPROPSTATUS_NOTSUPPORTED)
|
|
{
|
|
TESTC(dwOptions == DBPROPOPTIONS_REQUIRED);
|
|
odtLog << " Temp Table property was not supported with IAlterTable. " << ENDL;
|
|
}
|
|
else if( hr == DB_S_ERRORSOCCURRED && (pProp->dwStatus == DBPROPSTATUS_NOTSET || pProp->dwStatus == DBPROPSTATUS_NOTSUPPORTED))
|
|
{
|
|
|
|
TESTC(dwOptions == DBPROPOPTIONS_OPTIONAL);
|
|
odtLog << " Temp Table property was not supported with IAlterTable. " << ENDL;
|
|
}
|
|
else
|
|
{
|
|
if( fSupported && fSettable )
|
|
{
|
|
TESTC_(hr, S_OK);
|
|
|
|
// Verify TEMPTABLE property was added/removed
|
|
if( dbPropID == DBPROP_TBL_TEMPTABLE )
|
|
{
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Only other reason to fail is that the property is read only
|
|
TESTC_(hr, DB_E_ERRORSOCCURRED);
|
|
TESTC(pProp->dwStatus == DBPROPSTATUS_NOTSETTABLE);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
::FreeProperties(&cPropSets, &rgPropSets);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterInvalidTableProperties
|
|
//
|
|
// Test invalid property conditions
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterInvalidTableProperties
|
|
(
|
|
DBID * pTableID,
|
|
DBPROPSTATUS dwExpectedStatus,
|
|
DBPROPID dbPropID,
|
|
GUID guidPropertySet,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions,
|
|
DBID colid
|
|
)
|
|
{
|
|
HRESULT hrExpected;
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET * rgPropSets = NULL;
|
|
|
|
::SetProperty(dbPropID, guidPropertySet, &cPropSets, &rgPropSets,
|
|
pValue, wType, dwOptions, colid);
|
|
|
|
hrExpected = dwOptions == DBPROPOPTIONS_OPTIONAL ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED;
|
|
TESTC_(AlterTable(pTableID, NULL, cPropSets, rgPropSets), hrExpected);
|
|
|
|
TESTC(VerifyPropStatus(cPropSets, rgPropSets, dbPropID, guidPropertySet, dwExpectedStatus))
|
|
|
|
CLEANUP:
|
|
|
|
::FreeProperties(&cPropSets, &rgPropSets);
|
|
TRETURN
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumn
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumn
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags,
|
|
DBCOLUMNDESC * pColumnDesc,
|
|
CTable * pTable,
|
|
HRESULT * phr
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CCol TempCol;
|
|
CTable * pAlterTable = NULL;
|
|
|
|
if( pTable )
|
|
{
|
|
pAlterTable = pTable;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(m_pTable != NULL);
|
|
pAlterTable = m_pTable;
|
|
}
|
|
|
|
TESTC_(pAlterTable->GetColInfo(ulColumnOrdinal, TempCol), S_OK);
|
|
|
|
hr = AlterColumn(&pAlterTable->GetTableID(), TempCol.GetColID(),
|
|
ColumnDescFlags, pColumnDesc);
|
|
|
|
//On Error, we need to check for NOT_SUPPORTED property errors
|
|
//Loop over all property sets
|
|
if( hr == DB_S_ERRORSOCCURRED || hr == DB_E_ERRORSOCCURRED )
|
|
{
|
|
// DBCOLUMNDESCFLAGS_PROPERTIES must be requested
|
|
// for DB_E_ERROR*/DB_S_ERROR*
|
|
TESTC((ColumnDescFlags & DBCOLUMNDESCFLAGS_PROPERTIES) != 0);
|
|
TESTC(CheckUnsupportedProp(pColumnDesc->cPropertySets, pColumnDesc->rgPropertySets));
|
|
}
|
|
else
|
|
TESTC_(hr, S_OK);
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
TESTC(CompareColumnMetaData(ulColumnOrdinal, ColumnDescFlags, pColumnDesc, pTable));
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if( phr )
|
|
*phr = hr;
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumnName
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumnName
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBID * pNewColumnID
|
|
)
|
|
{
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
memset(&ColumnDesc, 0xCA, sizeof(DBCOLUMNDESC));
|
|
memcpy(&ColumnDesc.dbcid, pNewColumnID, sizeof(DBID));
|
|
|
|
return VerifyAlterColumn(ulColumnOrdinal, DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumnSize
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumnSize
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBLENGTH ulNewColSize,
|
|
CTable * pTable
|
|
)
|
|
{
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
memset(&ColumnDesc, 0xCA, sizeof(DBCOLUMNDESC));
|
|
ColumnDesc.ulColumnSize = ulNewColSize;
|
|
|
|
return VerifyAlterColumn(ulColumnOrdinal, DBCOLUMNDESCFLAGS_COLSIZE, &ColumnDesc, pTable);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumnPrecision
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumnPrecision
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
BYTE bNewPrecision
|
|
)
|
|
{
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
memset(&ColumnDesc, 0xCA, sizeof(DBCOLUMNDESC));
|
|
ColumnDesc.bPrecision = bNewPrecision;
|
|
|
|
return VerifyAlterColumn(ulColumnOrdinal, DBCOLUMNDESCFLAGS_PRECISION, &ColumnDesc);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumnScale
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumnScale
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
BYTE bNewScale
|
|
)
|
|
{
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
memset(&ColumnDesc, 0xCA, sizeof(DBCOLUMNDESC));
|
|
ColumnDesc.bScale = bNewScale;
|
|
|
|
return VerifyAlterColumn(ulColumnOrdinal, DBCOLUMNDESCFLAGS_SCALE, &ColumnDesc);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumnType
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumnType
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBTYPE wType,
|
|
CTable * pTable
|
|
)
|
|
{
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
memset(&ColumnDesc, 0xCA, sizeof(DBCOLUMNDESC));
|
|
ColumnDesc.wType = wType;
|
|
|
|
return VerifyAlterColumn(ulColumnOrdinal, DBCOLUMNDESCFLAGS_WTYPE, &ColumnDesc, pTable);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumnTypeName
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumnTypeName
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
WCHAR * pwszTypeName,
|
|
CTable * pTable
|
|
)
|
|
{
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
memset(&ColumnDesc, 0xCA, sizeof(DBCOLUMNDESC));
|
|
ColumnDesc.pwszTypeName = pwszTypeName;
|
|
|
|
return VerifyAlterColumn(ulColumnOrdinal, DBCOLUMNDESCFLAGS_TYPENAME, &ColumnDesc, pTable);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumnCLSID
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumnCLSID
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
CLSID * pclsid
|
|
)
|
|
{
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
memset(&ColumnDesc, 0xCA, sizeof(DBCOLUMNDESC));
|
|
ColumnDesc.pclsid = pclsid;
|
|
|
|
return VerifyAlterColumn(ulColumnOrdinal, DBCOLUMNDESCFLAGS_CLSID, &ColumnDesc);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterColumnProperty
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterColumnProperty
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBPROPID dbPropID,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions
|
|
)
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET * rgPropSets = NULL;
|
|
|
|
::SetProperty(dbPropID, DBPROPSET_COLUMN, &cPropSets, &rgPropSets,
|
|
pValue, wType, dwOptions);
|
|
|
|
memset(&ColumnDesc, 0xCA, sizeof(DBCOLUMNDESC));
|
|
ColumnDesc.cPropertySets = cPropSets;
|
|
ColumnDesc.rgPropertySets = rgPropSets;
|
|
|
|
TESTC(VerifyAlterColumn(ulColumnOrdinal, DBCOLUMNDESCFLAGS_PROPERTIES, &ColumnDesc));
|
|
|
|
CLEANUP:
|
|
|
|
::FreeProperties(&cPropSets, &rgPropSets);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyAlterInvalidColumnProperties
|
|
//
|
|
// Test invalid property conditions
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyAlterInvalidColumnProperties
|
|
(
|
|
CTable * pTable,
|
|
DBPROPSTATUS dwExpectedStatus,
|
|
DBPROPID dbPropID,
|
|
GUID guidPropertySet,
|
|
void * pValue,
|
|
DBTYPE wType,
|
|
DBPROPOPTIONS dwOptions,
|
|
DBID colid
|
|
)
|
|
{
|
|
HRESULT hrExpected;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
CCol col;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_PROPERTIES) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&ColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
TESTC_(pTable->GetColInfo(1, col), S_OK);
|
|
|
|
::SetProperty(dbPropID, guidPropertySet, &ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets,
|
|
pValue, wType, dwOptions, colid);
|
|
|
|
hrExpected = dwOptions == DBPROPOPTIONS_OPTIONAL ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED;
|
|
|
|
TESTC_(AlterColumn(&pTable->GetTableID(), col.GetColID(), DBCOLUMNDESCFLAGS_PROPERTIES, &ColumnDesc), hrExpected);
|
|
|
|
TESTC(VerifyPropStatus(ColumnDesc.cPropertySets, ColumnDesc.rgPropertySets, dbPropID, guidPropertySet, dwExpectedStatus))
|
|
|
|
CLEANUP:
|
|
|
|
::FreeProperties(&ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::CompareColumnMetaData
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::CompareColumnMetaData
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags,
|
|
DBCOLUMNDESC * pColumnDesc,
|
|
CTable * pTable
|
|
)
|
|
{
|
|
TBEGIN
|
|
BOOL fTypeChanged = FALSE;
|
|
CTable * pAlterTable = NULL;
|
|
CTable CurrentSchema(g_pIOpenRowset);
|
|
CTable * pPrevSchema = NULL;
|
|
IColumnsInfo * pIColumnsInfo = NULL;
|
|
CCol CachedColInfo;
|
|
CCol CurrentColInfo;
|
|
|
|
if( pTable )
|
|
{
|
|
pAlterTable = pTable;
|
|
pPrevSchema = pTable;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(m_pTable != NULL);
|
|
pAlterTable = m_pTable;
|
|
pPrevSchema = m_pSchema;
|
|
}
|
|
|
|
// Now get the rowset which we'll use to populate the table
|
|
TESTC_(pAlterTable->CreateRowset(USE_OPENROWSET, IID_IColumnsInfo, 0,
|
|
NULL, (IUnknown **)&pIColumnsInfo),S_OK);
|
|
TESTC_(CurrentSchema.GetTableColumnInfo(&pAlterTable->GetTableID(), pIColumnsInfo), S_OK);
|
|
TESTC_(CurrentSchema.AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, pAlterTable->GetTableName()), S_OK);
|
|
|
|
TESTC( CurrentSchema.CountColumnsOnSchema() == pPrevSchema->CountColumnsOnSchema() );
|
|
|
|
|
|
// Verify that the appropriate change has been made
|
|
TESTC_(pPrevSchema->GetColInfo(ulColumnOrdinal, CachedColInfo), S_OK);
|
|
TESTC_(CurrentSchema.GetColInfo(ulColumnOrdinal, CurrentColInfo), S_OK);
|
|
|
|
if( ColumnDescFlags & DBCOLUMNDESCFLAGS_DBCID )
|
|
{
|
|
TESTC(TCAlterCompareDBID(CurrentColInfo.GetColID(), &pColumnDesc->dbcid));
|
|
}
|
|
else
|
|
{
|
|
TESTC(TCAlterCompareDBID(CurrentColInfo.GetColID(), CachedColInfo.GetColID()));
|
|
}
|
|
|
|
// If the column type changes, ColumnSize, Precision, and Scale will all be affected
|
|
fTypeChanged = ColumnDescFlags & (DBCOLUMNDESCFLAGS_WTYPE | DBCOLUMNDESCFLAGS_TYPENAME);
|
|
if( fTypeChanged )
|
|
{
|
|
// When changing a column type, the test variation must call SetChangeColInfo
|
|
// to indicate the new type information
|
|
ASSERT(m_pChangedCol != NULL);
|
|
}
|
|
|
|
if( ColumnDescFlags & DBCOLUMNDESCFLAGS_WTYPE )
|
|
{
|
|
TESTC(CurrentColInfo.GetProviderType() == pColumnDesc->wType);
|
|
}
|
|
else
|
|
{
|
|
if( fTypeChanged )
|
|
{
|
|
TESTC(CurrentColInfo.GetProviderType() == m_pChangedCol->GetProviderType());
|
|
}
|
|
else
|
|
{
|
|
TESTC(CurrentColInfo.GetProviderType() == CachedColInfo.GetProviderType());
|
|
}
|
|
}
|
|
|
|
if( ColumnDescFlags & DBCOLUMNDESCFLAGS_TYPENAME )
|
|
{
|
|
// There is no way to derive a column's underlying typename once it is created.
|
|
// So, check the wType, FixedLength, and IsLong attributes
|
|
TESTC(CurrentColInfo.GetProviderType() == m_pChangedCol->GetProviderType());
|
|
TESTC(CurrentColInfo.GetIsLong() == m_pChangedCol->GetIsLong());
|
|
TESTC(CurrentColInfo.GetIsFixedLength() == m_pChangedCol->GetIsFixedLength());
|
|
}
|
|
|
|
// Column Size should only be applicable to non-BLOB STRING and BINARY types
|
|
if( (CurrentColInfo.GetProviderType() == DBTYPE_STR ||
|
|
CurrentColInfo.GetProviderType() == DBTYPE_WSTR ||
|
|
CurrentColInfo.GetProviderType() == DBTYPE_BYTES) &&
|
|
ColumnDescFlags & DBCOLUMNDESCFLAGS_COLSIZE )
|
|
{
|
|
TESTC(CurrentColInfo.GetColumnSize() == pColumnDesc->ulColumnSize);
|
|
}
|
|
else
|
|
{
|
|
if( !fTypeChanged )
|
|
{
|
|
TESTC(CurrentColInfo.GetColumnSize() == CachedColInfo.GetColumnSize());
|
|
}
|
|
else
|
|
{
|
|
if( CurrentColInfo.GetProviderType() == DBTYPE_STR ||
|
|
CurrentColInfo.GetProviderType() == DBTYPE_WSTR ||
|
|
CurrentColInfo.GetProviderType() == DBTYPE_BYTES )
|
|
{
|
|
TESTC(CurrentColInfo.GetColumnSize() == CachedColInfo.GetColumnSize());
|
|
}
|
|
else
|
|
{
|
|
TESTC(CurrentColInfo.GetColumnSize() == m_pChangedCol->GetColumnSize());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Precision should only be applicable to NUMERIC and VARNUMERIC types
|
|
if( (CurrentColInfo.GetProviderType() == DBTYPE_NUMERIC ||
|
|
CurrentColInfo.GetProviderType() == DBTYPE_VARNUMERIC) &&
|
|
(ColumnDescFlags & DBCOLUMNDESCFLAGS_PRECISION) )
|
|
{
|
|
TESTC(CurrentColInfo.GetPrecision() == pColumnDesc->bPrecision);
|
|
}
|
|
else
|
|
{
|
|
if( !fTypeChanged )
|
|
{
|
|
TESTC(CurrentColInfo.GetPrecision() == CachedColInfo.GetPrecision());
|
|
}
|
|
}
|
|
|
|
// Scale should only be applicable to NUMERIC, VARNUMERIC, and DECIMAL types
|
|
if( (CurrentColInfo.GetProviderType() == DBTYPE_NUMERIC ||
|
|
CurrentColInfo.GetProviderType() == DBTYPE_VARNUMERIC) &&
|
|
(ColumnDescFlags & DBCOLUMNDESCFLAGS_SCALE) )
|
|
{
|
|
TESTC(CurrentColInfo.GetScale() == pColumnDesc->bScale);
|
|
}
|
|
else
|
|
{
|
|
if( !fTypeChanged )
|
|
{
|
|
TESTC(CurrentColInfo.GetScale() == CachedColInfo.GetScale());
|
|
}
|
|
}
|
|
|
|
|
|
// The various properties
|
|
if( ColumnDescFlags & DBCOLUMNDESCFLAGS_PROPERTIES )
|
|
{
|
|
if( m_pChangedCol )
|
|
{
|
|
// DBPROP_COL_ISLONG
|
|
TESTC(CurrentColInfo.GetIsLong() == m_pChangedCol->GetIsLong());
|
|
|
|
// DBPROP_COL_FIXEDLENGTH
|
|
TESTC(CurrentColInfo.GetIsFixedLength() == m_pChangedCol->GetIsFixedLength());
|
|
|
|
// DBPROP_COL_NULLABLE
|
|
TESTC(CurrentColInfo.GetNullable() == m_pChangedCol->GetNullable());
|
|
|
|
// DBPROP_COL_DESCRIPTION
|
|
if(CurrentColInfo.GetColDescription(), m_pChangedCol->GetColDescription())
|
|
{
|
|
TESTC(0 == wcscmp(CurrentColInfo.GetColDescription(), m_pChangedCol->GetColDescription()));
|
|
}
|
|
else
|
|
{
|
|
TESTC( CurrentColInfo.GetColDescription() == NULL &&
|
|
m_pChangedCol->GetColDescription() == NULL);
|
|
}
|
|
|
|
// DBPROP_COL_COLUMNNLCID
|
|
TESTC(CurrentColInfo.GetLCID() == m_pChangedCol->GetLCID());
|
|
|
|
// DBPROP_COL_UNIQUE
|
|
// Uniqueness cannot be checked thru schema information
|
|
// Must actually try to violate unique constraint.
|
|
}
|
|
else
|
|
TERROR("No change col info.");
|
|
}
|
|
else
|
|
{
|
|
if( !fTypeChanged )
|
|
{
|
|
// DBPROP_COL_ISLONG
|
|
TESTC(CurrentColInfo.GetIsLong() == CachedColInfo.GetIsLong());
|
|
|
|
// DBPROP_COL_FIXEDLENGTH
|
|
TESTC(CurrentColInfo.GetIsFixedLength() == CachedColInfo.GetIsFixedLength());
|
|
|
|
// DBPROP_COL_NULLABLE
|
|
TESTC(CurrentColInfo.GetNullable() == CachedColInfo.GetNullable());
|
|
|
|
// DBPROP_COL_DESCRIPTION
|
|
if(CurrentColInfo.GetColDescription(), CachedColInfo.GetColDescription())
|
|
{
|
|
TESTC(0 == wcscmp(CurrentColInfo.GetColDescription(), CachedColInfo.GetColDescription()));
|
|
}
|
|
else
|
|
{
|
|
TESTC( CurrentColInfo.GetColDescription() == NULL &&
|
|
CachedColInfo.GetColDescription() == NULL);
|
|
}
|
|
|
|
// DBPROP_COL_UNIQUE
|
|
// Uniqueness cannot be checked thru schema information
|
|
// Must actually try to violate unique constraint.
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
|
|
if( pTable == NULL )
|
|
{
|
|
// Only restore column if the using m_pTable which must be re-used for
|
|
// variations
|
|
RestoreColumnID(ulColumnOrdinal, CurrentColInfo.GetColID(), ColumnDescFlags);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::MakeNewID
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::MakeNewID
|
|
(
|
|
DBID * pDBID,
|
|
DBKINDENUM eKind,
|
|
size_t ulLen
|
|
)
|
|
{
|
|
ASSERT(pDBID);
|
|
|
|
WCHAR * pwszName = NULL;
|
|
size_t cchName = 0;
|
|
size_t cIter = 0;
|
|
|
|
memset(pDBID, 0, sizeof(DBID));
|
|
pDBID->eKind = eKind;
|
|
|
|
if( eKind == DBKIND_NAME )
|
|
{
|
|
pwszName = MakeObjectName(m_pTable->GetModuleName(), ulLen);
|
|
if( !pwszName )
|
|
return E_OUTOFMEMORY;
|
|
|
|
cchName = wcslen(pwszName);
|
|
if( cchName < ulLen)
|
|
{
|
|
WCHAR * pwszNewName = (WCHAR *)PROVIDER_ALLOC(sizeof(WCHAR)*(ulLen+1));
|
|
|
|
if( pwszNewName == NULL)
|
|
{
|
|
PROVIDER_FREE(pwszName);
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
pwszNewName[0] = L'\0';
|
|
|
|
for ( cIter = 0; cIter < ulLen - cchName; cIter += cchName)
|
|
wcscat(pwszNewName, pwszName);
|
|
|
|
wcsncat(pwszNewName, pwszName, ulLen-cIter);
|
|
PROVIDER_FREE(pwszName);
|
|
pwszName = pwszNewName;
|
|
|
|
}
|
|
else if( cchName > ulLen )
|
|
{
|
|
ASSERT(!"MakeObjectName did not honor ulLen");
|
|
}
|
|
|
|
pDBID->uName.pwszName = pwszName;
|
|
|
|
return S_OK;
|
|
}
|
|
else
|
|
return DB_E_NOTSUPPORTED;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::MakeNewTableID
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::MakeNewTableID
|
|
(
|
|
DBID * pTableID,
|
|
DBKINDENUM eKind,
|
|
size_t ulLen
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fExists = TRUE;
|
|
|
|
TESTC_(hr = MakeNewID(pTableID, eKind, ulLen), S_OK);
|
|
|
|
// Verify that the table does not already exist.
|
|
TESTC_(hr = m_pTable->DoesTableExist(pTableID, &fExists), S_OK);
|
|
|
|
// Couldn't create a new DBID
|
|
if( fExists )
|
|
return S_FALSE;
|
|
|
|
CLEANUP:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::MakeNewColumnID
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::MakeNewColumnID
|
|
(
|
|
DBID * pNewColumnID,
|
|
DBKINDENUM eKind,
|
|
size_t ulLen
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fExists = TRUE;
|
|
ULONG cIter;
|
|
CCol TempCol;
|
|
|
|
TESTC_(hr = MakeNewID(pNewColumnID, eKind, ulLen), S_OK);
|
|
|
|
// Verify that the table does not already have this columnID
|
|
for ( cIter = 1; cIter <= m_pSchema->CountColumnsOnSchema(); cIter++)
|
|
{
|
|
TESTC_(m_pSchema->GetColInfo(cIter, TempCol), S_OK);
|
|
|
|
if( CompareDBID(*TempCol.GetColID(), *pNewColumnID) )
|
|
{
|
|
// Couldn't create a new DBID
|
|
hr = S_FALSE;
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
CLEANUP:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::RestoreTableID
|
|
//
|
|
// To be called to restore the table name, back to its orginal state
|
|
// E.g. A test variation changes the table ID to pCurrentID.
|
|
// Then the variation should clean up after itself by changing pCurrentID
|
|
// back to its original form, m_pTableID
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::RestoreTableID
|
|
(
|
|
DBID * pCurrentID
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Try calling AlterTable
|
|
hr = AlterTable(pCurrentID, &m_TableID);
|
|
|
|
// If AlterTable fails, log a failure
|
|
COMPARE( SUCCEEDED(hr), TRUE);
|
|
if( FAILED(hr) )
|
|
{
|
|
hr = E_FAIL;
|
|
|
|
// Must be more drastic
|
|
// Try to delete the whole table.
|
|
m_pTable->DropTable();
|
|
SAFE_DELETE(m_pTable);
|
|
ReleaseDBID(&m_TableID, FALSE);
|
|
|
|
m_pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(m_pTable != NULL)
|
|
TESTC_(hr = m_pTable->CreateTable(0,COL_ONE,NULL,PRIMARY,TRUE),S_OK);
|
|
|
|
TESTC_(hr = DuplicateDBID(m_pTable->GetTableID(), &m_TableID), S_OK);
|
|
m_lDBIDType = (DBKINDENUM)m_TableID.eKind;
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::RestoreColumnID
|
|
//
|
|
// To be called to restore a Column back to its original state
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::RestoreColumnID
|
|
(
|
|
DBORDINAL ulColumnOrdinal,
|
|
DBID * pCurrentID,
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CCol CachedCol;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
IColumnsInfo * pIColumnsInfo = NULL;
|
|
|
|
// Try calling AlterColumn
|
|
TESTC_(m_pTable->GetColInfo(ulColumnOrdinal, CachedCol), S_OK);
|
|
TESTC_(m_pTable->BuildColumnDesc(&ColumnDesc, CachedCol), S_OK);
|
|
hr = AlterColumn(&m_pTable->GetTableID(), pCurrentID, ColumnDescFlags, &ColumnDesc);
|
|
|
|
// If AlterColumn fails, log a failure
|
|
COMPARE( SUCCEEDED(hr), TRUE);
|
|
if( FAILED(hr) )
|
|
{
|
|
// Must be more drastic
|
|
// Try to delete the whole table.
|
|
m_pTable->DropTable();
|
|
SAFE_DELETE(m_pTable);
|
|
ReleaseDBID(&m_TableID, FALSE);
|
|
|
|
m_pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(m_pTable != NULL)
|
|
TESTC_(m_pTable->CreateTable(0,COL_ONE,NULL,PRIMARY,TRUE),S_OK);
|
|
|
|
TESTC_(DuplicateDBID(m_pTable->GetTableID(), &m_TableID), S_OK);
|
|
m_lDBIDType = (DBKINDENUM)m_TableID.eKind;
|
|
|
|
// Re-Cache column metadata using CSchema object
|
|
SAFE_DELETE(m_pSchema);
|
|
m_pSchema = new CTable(g_pIOpenRowset);
|
|
|
|
// Now get the rowset which we'll use to populate the table
|
|
TESTC_(m_pTable->CreateRowset(USE_OPENROWSET, IID_IColumnsInfo, 0,
|
|
NULL, (IUnknown **)&pIColumnsInfo),S_OK);
|
|
TESTC_(m_pSchema->GetTableColumnInfo(&m_pTable->GetTableID(), pIColumnsInfo), S_OK);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseColumnDesc(&ColumnDesc, 1, FALSE);
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::CreateTable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::CreateTable
|
|
(
|
|
CTable ** ppTable
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
CTable * pTable = NULL;
|
|
|
|
ASSERT(ppTable);
|
|
|
|
*ppTable = NULL;
|
|
|
|
pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(pTable != NULL);
|
|
|
|
TESTC_(hr = pTable->CreateTable(SIZEOF_TABLE,COL_ONE,NULL,PRIMARY,TRUE), S_OK);
|
|
|
|
CLEANUP:
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
*ppTable = pTable;
|
|
}
|
|
else
|
|
{
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::CreateTable
|
|
//
|
|
// Creates a Table using ITableDefinition
|
|
// with the requested table property
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::CreateTable
|
|
(
|
|
CTable ** ppTable,
|
|
DBPROPID dbPropID,
|
|
void * pValue,
|
|
DBPROPOPTIONS dwOptions
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
CTable * pTable = NULL;
|
|
DBID dbid;
|
|
DBID * pdbid = &dbid;
|
|
ULONG cPropSets = NULL;
|
|
DBPROPSET * rgPropSets = NULL;
|
|
|
|
ASSERT(ppTable);
|
|
|
|
*ppTable = NULL;
|
|
|
|
::SetProperty(dbPropID, DBPROPSET_TABLE, &cPropSets, &rgPropSets,
|
|
pValue, DBTYPE_BOOL, dwOptions);
|
|
|
|
pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(pTable != NULL);
|
|
|
|
pTable->SetPropertySets(rgPropSets, cPropSets);
|
|
pTable->ResetInputTableID();
|
|
pTable->SetDBID(&pdbid);
|
|
TEST2C_(hr = pTable->CreateTable(SIZEOF_TABLE,COL_ONE,NULL,PRIMARY,TRUE), S_OK, DB_E_ERRORSOCCURRED);
|
|
|
|
// If requested property was not supported,
|
|
// return S_FALSE to indication that the variation should not continue
|
|
if( hr == DB_E_ERRORSOCCURRED )
|
|
{
|
|
hr = S_FALSE;
|
|
SAFE_DELETE(pTable);
|
|
goto CLEANUP;
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
*ppTable = pTable;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::CreateOneColTableWithProps
|
|
//
|
|
// Creates a Table that has one column (based on the info in pCol)
|
|
// with the requested column properties
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::CreateOneColTableWithProps
|
|
(
|
|
CTable ** ppTable,
|
|
CCol * pCol,
|
|
ULONG cPropSets,
|
|
DBPROPSET * rgPropSets
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
DBCOLUMNDESC * pColumnDesc = NULL;
|
|
CTable * pTable = NULL;
|
|
|
|
ASSERT(ppTable);
|
|
|
|
*ppTable = NULL;
|
|
|
|
pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(pTable != NULL);
|
|
|
|
// Based new column attributes on pCol
|
|
pColumnDesc = (DBCOLUMNDESC *)PROVIDER_ALLOC(sizeof(DBCOLUMNDESC));
|
|
TESTC(pColumnDesc != NULL);
|
|
TESTC_(hr = pTable->BuildColumnDesc(pColumnDesc, *pCol), S_OK);
|
|
|
|
// Discard any properties and replace with the user specified properties
|
|
::FreeProperties(&pColumnDesc->cPropertySets, &pColumnDesc->rgPropertySets);
|
|
TESTC(DuplicatePropertySets(cPropSets, rgPropSets,
|
|
&pColumnDesc->cPropertySets, &pColumnDesc->rgPropertySets));
|
|
|
|
TESTC_(hr = MakeNewColumnID(&pColumnDesc->dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
pTable->SetBuildColumnDesc(FALSE);
|
|
pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
TESTC_(hr = pTable->CreateTable(0,0,NULL,PRIMARY,TRUE), S_OK);
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
*ppTable = pTable;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyNonTableProps
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyNonTableProps
|
|
(
|
|
DBPROPOPTIONS dwOptions
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBPROPSTATUS dwExpectedStatus;
|
|
CTable * pTable = NULL;
|
|
|
|
dwExpectedStatus = dwOptions == DBPROPOPTIONS_REQUIRED ? DBPROPSTATUS_NOTSUPPORTED : DBPROPSTATUS_NOTSET;
|
|
|
|
TESTC_(hr = CreateTable(&pTable), S_OK);
|
|
|
|
// Column Property
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus,
|
|
DBPROP_COL_AUTOINCREMENT, DBPROPSET_COLUMN, (void *)VARIANT_TRUE, DBTYPE_BOOL, dwOptions));
|
|
|
|
// DataSource Property
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus,
|
|
DBPROP_MULTIPLECONNECTIONS, DBPROPSET_DATASOURCE, (void *)VARIANT_TRUE, DBTYPE_BOOL, dwOptions));
|
|
|
|
// DataSource Info Property
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus, DBPROP_ALTERCOLUMN,
|
|
DBPROPSET_DATASOURCEINFO, (void *)LONG_MAX, DBTYPE_I4, dwOptions));
|
|
|
|
// Index Property
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus, DBPROP_INDEX_UNIQUE,
|
|
DBPROPSET_INDEX, (void *)VARIANT_FALSE, DBTYPE_BOOL, dwOptions));
|
|
|
|
// Initialization Property
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus, DBPROP_AUTH_PASSWORD,
|
|
DBPROPSET_DBINIT, (void *)L"FOO", DBTYPE_BSTR, dwOptions));
|
|
|
|
// Rowset Property
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus, DBPROP_IRowset,
|
|
DBPROPSET_ROWSET, (void *)VARIANT_TRUE, DBTYPE_BOOL, dwOptions));
|
|
|
|
// Session Property
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus, DBPROP_SESS_AUTOCOMMITISOLEVELS,
|
|
DBPROPSET_SESSION, (void *)0, DBTYPE_I4, dwOptions));
|
|
|
|
// View Property
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus, DBPROP_MAXORSINFILTER,
|
|
DBPROPSET_VIEW, (void *)1, DBTYPE_I4, dwOptions));
|
|
|
|
// Table Property with Bad PROPSET GUID
|
|
TESTC(VerifyAlterInvalidTableProperties(&pTable->GetTableID(), dwExpectedStatus, DBPROP_TBL_TEMPTABLE,
|
|
DBPROPSET_COLUMN, (void *)VARIANT_TRUE, DBTYPE_BOOL, dwOptions));
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::SetChangeColInfo
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
HRESULT TCIAlterTable::SetChangeColInfo
|
|
(
|
|
CCol * pCol
|
|
)
|
|
{
|
|
m_pChangedCol = pCol;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::GetReadOnlySession
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::GetReadOnlySession
|
|
(
|
|
IUnknown ** ppUnkReadSession
|
|
)
|
|
{
|
|
TBEGIN
|
|
ULONG cPropSets;
|
|
DBPROPSET * rgPropSets = NULL;
|
|
IDBInitialize * pIDBInitialize = NULL;
|
|
IDBProperties * pIDBProperties = NULL;
|
|
|
|
ASSERT(ppUnkReadSession != NULL);
|
|
|
|
*ppUnkReadSession = NULL;
|
|
|
|
//Obtain a new uninitialized DSO
|
|
TESTC_(CreateNewDSO(NULL, IID_IDBInitialize, (IUnknown**)&pIDBInitialize, CREATEDSO_NONE), S_OK);
|
|
|
|
TESTC(VerifyInterface(pIDBInitialize, IID_IDBProperties, DATASOURCE_INTERFACE, (IUnknown **)&pIDBProperties));
|
|
|
|
//Build our init options from string passed to us from the LTM InitString
|
|
GetInitProps(&cPropSets,&rgPropSets);
|
|
|
|
// Add Property DBPROP_INIT_MODE
|
|
::SetProperty(DBPROP_INIT_MODE, DBPROPSET_DBINIT, &cPropSets,
|
|
&rgPropSets, (void *)DB_MODE_READ, DBTYPE_I4, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(QI(pIDBInitialize, IID_IDBProperties, (void**)&pIDBProperties), S_OK)
|
|
QTESTC_(pIDBProperties->SetProperties(cPropSets,rgPropSets), S_OK)
|
|
|
|
QTESTC_(pIDBInitialize->Initialize(),S_OK)
|
|
|
|
//Obtain IAlterTable
|
|
TESTC_(CreateNewSession(pIDBInitialize, IID_IUnknown, ppUnkReadSession), S_OK);
|
|
|
|
CLEANUP:
|
|
|
|
::FreeProperties(&cPropSets, &rgPropSets);
|
|
|
|
SAFE_RELEASE(pIDBInitialize);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::AlterPropertyAndVerifyRowset
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::AlterPropertyAndVerifyRowset
|
|
(
|
|
DBPROPID dbPropID
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBORDINAL ulOrdinal = 0;
|
|
CCol col;
|
|
CCol onetablecol;
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES;
|
|
CTable * pTable = NULL;
|
|
|
|
ASSERT(dbPropID == DBPROP_COL_UNIQUE || dbPropID == DBPROP_COL_PRIMARYKEY ||
|
|
dbPropID == DBPROP_COL_DEFAULT || dbPropID == DBPROP_COL_AUTOINCREMENT );
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_PROPERTIES) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
// For each column in our Table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
DBCOLUMNDESC * pColumnDesc = NULL;
|
|
DBCOLUMNDESC AlterColumnDesc;
|
|
CCol onetablecol;
|
|
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
if( dbPropID == DBPROP_COL_AUTOINCREMENT )
|
|
{
|
|
if( !col.CanAutoInc() )
|
|
continue;
|
|
}
|
|
else if( dbPropID == DBPROP_COL_DEFAULT )
|
|
{
|
|
if( !col.GetUpdateable() )
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if( col.GetIsLong() || col.GetAutoInc() || !col.GetUpdateable() || col.GetProviderType() == DBTYPE_BOOL )
|
|
continue;
|
|
}
|
|
|
|
odtLog << "Changing Property: " << GetPropertyName(dbPropID, DBPROPSET_COLUMN) << " on type: "<< col.GetProviderTypeName() << ENDL;
|
|
|
|
pColumnDesc = (DBCOLUMNDESC *)PROVIDER_ALLOC(sizeof(DBCOLUMNDESC));
|
|
TESTC(pColumnDesc != NULL);
|
|
TESTC_(m_pTable->BuildColumnDesc(pColumnDesc, col), S_OK);
|
|
|
|
TESTC_(MakeNewColumnID(&pColumnDesc->dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
// Create a fresh table for this variation
|
|
pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(pTable != NULL);
|
|
|
|
pColumnDesc->ulColumnSize = 1;
|
|
|
|
if( dbPropID == DBPROP_COL_PRIMARYKEY )
|
|
{
|
|
::SetProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN, &pColumnDesc->cPropertySets,
|
|
&pColumnDesc->rgPropertySets, (void *)VARIANT_FALSE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
|
|
pTable->SetBuildColumnDesc(FALSE);
|
|
pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
TESTC_(pTable->CreateTable(0,0,NULL,PRIMARY,TRUE), S_OK);
|
|
TESTC_(pTable->GetColInfo(1, onetablecol), S_OK);
|
|
|
|
memset(&AlterColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
// Set Appropriate Property
|
|
if( dbPropID == DBPROP_COL_DEFAULT )
|
|
{
|
|
DBTYPE wType;
|
|
void * pData = NULL;
|
|
|
|
TESTC(MakeDefaultData(&onetablecol, &pData, &wType, pTable));
|
|
|
|
::SetProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN, &AlterColumnDesc.cPropertySets,
|
|
&AlterColumnDesc.rgPropertySets, pData, wType, DBPROPOPTIONS_REQUIRED);
|
|
|
|
SAFE_FREE(pData);
|
|
}
|
|
else
|
|
{
|
|
::SetProperty(dbPropID, DBPROPSET_COLUMN, &AlterColumnDesc.cPropertySets,
|
|
&AlterColumnDesc.rgPropertySets, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
|
|
hr = AlterColumn(&pTable->GetTableID(), onetablecol.GetColID(),
|
|
ColumnDescFlags, &AlterColumnDesc);
|
|
|
|
if( hr == S_OK )
|
|
{
|
|
if( dbPropID == DBPROP_COL_UNIQUE || dbPropID == DBPROP_COL_PRIMARYKEY )
|
|
{
|
|
// Insert a row using IRowsetChange::InsertRow
|
|
if(CHECK(pTable->Insert(PRIMARY, 1), S_OK))
|
|
{
|
|
// Insert the same row again to violate UNIQUE constraint.
|
|
hr = pTable->Insert(PRIMARY, 1);
|
|
COMPARE(hr == DB_E_INTEGRITYVIOLATION || hr == DB_E_ERRORSOCCURRED, TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
COMPARE(VerifyRowsetValues(pTable, dbPropID), TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CHECK(hr, DB_E_ERRORSOCCURRED);
|
|
COMPARE(CheckUnsupportedProp(AlterColumnDesc.cPropertySets, AlterColumnDesc.rgPropertySets), TRUE);
|
|
}
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyRowsetValues
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyRowsetValues
|
|
(
|
|
CTable * pTable,
|
|
DBPROPID dbPropID
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
const ULONG cAutoInc = 2;
|
|
CRowsetChange Rowset;
|
|
HACCESSOR hAccessor;
|
|
DBCOUNTITEM cBindings = 0;
|
|
DBBINDING * rgBindings = NULL;
|
|
BYTE * pData = NULL;
|
|
HROW rghRow[cAutoInc];
|
|
void * rgpData[cAutoInc];
|
|
ULONG cIter;
|
|
|
|
memset(rgpData, 0, sizeof(rgpData));
|
|
|
|
Rowset.SetTable(pTable, DELETETABLE_NO);
|
|
Rowset.SetSettableProperty(DBPROP_IRowsetChange, DBPROPSET_ROWSET);
|
|
|
|
TESTC_(Rowset.CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, pTable, DBACCESSOR_ROWDATA,
|
|
DBPART_ALL, ALL_COLS_BOUND, FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, BLOB_LONG), S_OK);
|
|
|
|
TESTC_(Rowset.CreateAccessor(&hAccessor, DBACCESSOR_ROWDATA, DBPART_LENGTH | DBPART_VALUE | DBPART_STATUS,
|
|
&cBindings, &rgBindings, NULL, BLOB_LONG, NULL, ALL_COLS_BOUND | NOBOOKMARK_COLS_BOUND,
|
|
NO_COLS_BY_REF, DBTYPE_EMPTY), S_OK);
|
|
TESTC(cBindings == 1);
|
|
TESTC_(hr = FillInputBindings(pTable, DBACCESSOR_ROWDATA, cBindings, rgBindings,
|
|
&pData, 1, 0, NULL),S_OK);
|
|
|
|
if( dbPropID == DBPROP_COL_DEFAULT )
|
|
{
|
|
*(DBSTATUS *)(pData+rgBindings[0].obStatus) = DBSTATUS_S_DEFAULT;
|
|
TESTC_(Rowset.pIRowsetChange()->InsertRow(NULL, hAccessor, pData, NULL), S_OK);
|
|
}
|
|
else if( dbPropID == DBPROP_COL_AUTOINCREMENT )
|
|
{
|
|
*(DBSTATUS *)(pData+rgBindings[0].obStatus) = DBSTATUS_S_IGNORE;
|
|
|
|
// Insert the autoinc values
|
|
for( cIter = 0; cIter < cAutoInc; cIter++ )
|
|
{
|
|
TESTC_(Rowset.pIRowsetChange()->InsertRow(NULL, hAccessor, pData, NULL), S_OK);
|
|
}
|
|
}
|
|
|
|
TESTC(SUCCEEDED(Rowset.pIRowset()->RestartPosition(NULL)));
|
|
|
|
if( dbPropID == DBPROP_COL_DEFAULT )
|
|
{
|
|
TESTC(Rowset.VerifyAllRows());
|
|
}
|
|
else if( dbPropID == DBPROP_COL_AUTOINCREMENT )
|
|
{
|
|
TESTC_(Rowset.GetNextRows(cAutoInc, rghRow), S_OK);
|
|
TESTC_(Rowset.GetRowData(cAutoInc, rghRow, rgpData), S_OK);
|
|
|
|
// Assume seed to 1 and increment to be 1 by default.
|
|
LONG lAutoIncVal = 1;
|
|
LONG lInc = 1;
|
|
|
|
for( cIter = 0; cIter < cAutoInc; cIter++, lAutoIncVal += lInc )
|
|
{
|
|
WCHAR wszAutoInc[80];
|
|
void * pBackEndData = NULL;
|
|
|
|
_ltow(lAutoIncVal, wszAutoInc, 10);
|
|
pBackEndData = WSTR2DBTYPE(wszAutoInc, rgBindings[0].wType, NULL);
|
|
TESTC(pBackEndData != NULL);
|
|
|
|
TESTC(*(DBSTATUS *)((BYTE *)rgpData[cIter]+rgBindings[0].obStatus) == DBSTATUS_S_OK);
|
|
|
|
TESTC(CompareDBTypeData((BYTE *)rgpData[cIter]+rgBindings[0].obValue, pBackEndData, rgBindings[0].wType,
|
|
0, rgBindings[0].bPrecision, rgBindings[0].bScale, NULL));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_FREE(rgBindings);
|
|
Rowset.ReleaseRowData(pData, hAccessor);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::UpgradeType
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::UpgradeType
|
|
(
|
|
CCol * pCurrentCol,
|
|
CCol * pNewCol,
|
|
BOOL fAllowLong
|
|
)
|
|
{
|
|
TBEGIN
|
|
DBORDINAL ulOrdinal;
|
|
CCol schemacol;
|
|
CCol tablecol;
|
|
|
|
ASSERT(pCurrentCol && pNewCol);
|
|
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pSchema->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pSchema->GetColInfo(ulOrdinal, schemacol), S_OK);
|
|
|
|
if( IsTypeGreater(pCurrentCol, &schemacol) )
|
|
{
|
|
if( fAllowLong || !schemacol.GetIsLong() )
|
|
{
|
|
// Copy the new information
|
|
*pNewCol = schemacol;
|
|
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, tablecol), S_OK);
|
|
|
|
pNewCol->SetProviderTypeName(tablecol.GetProviderTypeName());
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
// no compatible type found
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::IsTypeGreater
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::IsTypeGreater
|
|
(
|
|
CCol * pCurCol,
|
|
CCol * pNewCol
|
|
)
|
|
{
|
|
TBEGIN
|
|
ASSERT(pCurCol && pNewCol);
|
|
|
|
ULONG CurColClass = GetTypeClass(pCurCol->GetProviderType());
|
|
ULONG NewColClass = GetTypeClass(pNewCol->GetProviderType());
|
|
|
|
if( CurColClass == CLASS_SPECIAL )
|
|
return FALSE;
|
|
|
|
if( CurColClass == NewColClass )
|
|
{
|
|
ULONG CurColRank = GetTypeRank(pCurCol->GetProviderType());
|
|
ULONG NewColRank = GetTypeRank(pNewCol->GetProviderType());
|
|
|
|
if( CurColRank > NewColRank )
|
|
return FALSE;
|
|
|
|
if( CurColRank == NewColRank )
|
|
{
|
|
if( pCurCol->GetProviderType() == pNewCol->GetProviderType() &&
|
|
pCurCol->GetIsFixedLength() == pNewCol->GetIsFixedLength() &&
|
|
pCurCol->GetIsLong() == pNewCol->GetIsLong() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if( pCurCol->GetProviderType() == DBTYPE_CY || pCurCol->GetProviderType() == DBTYPE_DBTIMESTAMP )
|
|
{
|
|
if( pCurCol->GetPrecision() <= pNewCol->GetPrecision() )
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::GetTypeClass
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
ULONG TCIAlterTable::GetTypeClass
|
|
(
|
|
DBTYPE wType
|
|
)
|
|
{
|
|
switch( wType )
|
|
{
|
|
case DBTYPE_I1:
|
|
case DBTYPE_I2:
|
|
case DBTYPE_I4:
|
|
case DBTYPE_I8:
|
|
return CLASS_SIGNEDINT;
|
|
case DBTYPE_UI1:
|
|
case DBTYPE_UI2:
|
|
case DBTYPE_UI4:
|
|
case DBTYPE_UI8:
|
|
return CLASS_UNSIGNEDINT;
|
|
case DBTYPE_R4:
|
|
case DBTYPE_R8:
|
|
return CLASS_APPROXNUM;
|
|
case DBTYPE_CY:
|
|
case DBTYPE_DECIMAL:
|
|
case DBTYPE_NUMERIC:
|
|
case DBTYPE_VARNUMERIC:
|
|
return CLASS_SCALEDINT;
|
|
case DBTYPE_DBTIME:
|
|
case DBTYPE_DBDATE:
|
|
case DBTYPE_DATE:
|
|
case DBTYPE_DBTIMESTAMP:
|
|
return CLASS_DATE;
|
|
case DBTYPE_STR:
|
|
case DBTYPE_WSTR:
|
|
case DBTYPE_BSTR:
|
|
return CLASS_STRING;
|
|
default:
|
|
return CLASS_SPECIAL;
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::GetTypeRank
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
ULONG TCIAlterTable::GetTypeRank
|
|
(
|
|
DBTYPE wType
|
|
)
|
|
{
|
|
switch( wType )
|
|
{
|
|
// signed int
|
|
case DBTYPE_I1:
|
|
return 1;
|
|
case DBTYPE_I2:
|
|
return 2;
|
|
case DBTYPE_I4:
|
|
return 3;
|
|
case DBTYPE_I8:
|
|
return 4;
|
|
|
|
// unsigned int
|
|
case DBTYPE_UI1:
|
|
return 1;
|
|
case DBTYPE_UI2:
|
|
return 2;
|
|
case DBTYPE_UI4:
|
|
return 3;
|
|
case DBTYPE_UI8:
|
|
return 4;
|
|
|
|
// approx num
|
|
case DBTYPE_R4:
|
|
return 1;
|
|
case DBTYPE_R8:
|
|
return 2;
|
|
|
|
// scaled int
|
|
case DBTYPE_CY:
|
|
return 1;
|
|
case DBTYPE_DECIMAL:
|
|
return 2;
|
|
case DBTYPE_NUMERIC:
|
|
return 3;
|
|
case DBTYPE_VARNUMERIC:
|
|
return 4;
|
|
|
|
// date
|
|
case DBTYPE_DBTIME:
|
|
return 1;
|
|
case DBTYPE_DBDATE:
|
|
return 2;
|
|
case DBTYPE_DATE:
|
|
return 3;
|
|
case DBTYPE_DBTIMESTAMP:
|
|
return 4;
|
|
|
|
// string
|
|
case DBTYPE_STR:
|
|
return 1;
|
|
case DBTYPE_WSTR:
|
|
return 2;
|
|
case DBTYPE_BSTR:
|
|
return 3;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::MakeDefaultData
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::MakeDefaultData
|
|
(
|
|
CCol * pCol,
|
|
void ** ppData,
|
|
DBTYPE * pwType,
|
|
CTable * pTable
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
DBTYPE wType;
|
|
void * pData = NULL;
|
|
VARIANT * pVar = NULL;
|
|
DBLENGTH cb = 0;
|
|
WCHAR wszData[(MAX_COL_SIZE+1)*sizeof(WCHAR)];
|
|
DBTYPE vt;
|
|
|
|
ASSERT(pCol && ppData && pwType && pTable);
|
|
|
|
*ppData = NULL;
|
|
*pwType = INVALID_DBTYPE;
|
|
|
|
TESTC_(pCol->MakeData(wszData, 1, PRIMARY, USENULLS, &vt, 0), S_OK);
|
|
|
|
if( pCol->GetProviderType() == DBTYPE_VARIANT )
|
|
{
|
|
pData = WSTR2DBTYPE_EX(wszData, vt, &cb);
|
|
hr = MapDBTYPE2VARIANT(pData, vt, cb, &pVar);
|
|
}
|
|
else
|
|
{
|
|
pData = WSTR2DBTYPE_EX(wszData, pCol->GetProviderType(), &cb);
|
|
hr = MapDBTYPE2VARIANT(pData, pCol->GetProviderType(), cb, &pVar);
|
|
}
|
|
|
|
if( S_OK == hr )
|
|
{
|
|
SAFE_FREE(pData);
|
|
pData = pVar;
|
|
|
|
wType = DBTYPE_VARIANT;
|
|
}
|
|
else
|
|
{
|
|
WCHAR * pwszFormattedData = NULL;
|
|
|
|
TESTC_(hr, S_FALSE);
|
|
|
|
TESTC_(pTable->GetLiteralAndValue(*pCol, &pwszFormattedData, 1, pCol->GetColNum(), PRIMARY, TRUE), S_OK);
|
|
|
|
pData = wcsDuplicate(pwszFormattedData);
|
|
wType = DBTYPE_BSTR;
|
|
}
|
|
|
|
if( pData )
|
|
{
|
|
*ppData = pData;
|
|
*pwType = wType;
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::ReleaseDefaultData
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void TCIAlterTable::ReleaseDefaultData
|
|
(
|
|
void * pDefaultData,
|
|
DBTYPE wDefaultType
|
|
)
|
|
{
|
|
if( pDefaultData && wDefaultType == DBTYPE_VARIANT )
|
|
{
|
|
VariantClear((VARIANT *)pDefaultData);
|
|
}
|
|
|
|
SAFE_FREE(pDefaultData);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyTableDefault
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyTableDefault
|
|
(
|
|
CTable * pTable,
|
|
BOOL fDefaultExists
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
BOOL fPass = FALSE;
|
|
BOOL fCheckDefault = FALSE;
|
|
CRowsetChange Rowset;
|
|
HACCESSOR hAccessor;
|
|
DBCOUNTITEM cBindings = 0;
|
|
DBBINDING * rgBindings = NULL;
|
|
BYTE * pData = NULL;
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HROW rghRow[1];
|
|
|
|
Rowset.SetTable(pTable, DELETETABLE_NO);
|
|
Rowset.SetSettableProperty(DBPROP_IRowsetChange, DBPROPSET_ROWSET);
|
|
|
|
TESTC_(Rowset.CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, pTable, DBACCESSOR_ROWDATA,
|
|
DBPART_ALL, ALL_COLS_BOUND, FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, BLOB_LONG), S_OK);
|
|
|
|
TESTC_(Rowset.CreateAccessor(&hAccessor, DBACCESSOR_ROWDATA, DBPART_LENGTH | DBPART_VALUE | DBPART_STATUS,
|
|
&cBindings, &rgBindings, NULL, BLOB_LONG, NULL, ALL_COLS_BOUND | NOBOOKMARK_COLS_BOUND,
|
|
NO_COLS_BY_REF, DBTYPE_EMPTY), S_OK);
|
|
|
|
TESTC(cBindings == 1);
|
|
TESTC_(hr = FillInputBindings(pTable, DBACCESSOR_ROWDATA, cBindings, rgBindings,
|
|
&pData, 1, 0, NULL),S_OK);
|
|
|
|
*(DBSTATUS *)(pData+rgBindings[0].obStatus) = DBSTATUS_S_DEFAULT;
|
|
|
|
hr = Rowset.pIRowsetChange()->InsertRow(NULL, hAccessor, pData, NULL);
|
|
if( FAILED(hr) )
|
|
{
|
|
// InsertRow could fail if default value does not exist
|
|
if( fDefaultExists == FALSE )
|
|
fPass = TRUE;
|
|
|
|
// Verification complete
|
|
goto CLEANUP;
|
|
}
|
|
|
|
TESTC(SUCCEEDED(Rowset.pIRowset()->RestartPosition(NULL)));
|
|
|
|
SAFE_FREE(pData);
|
|
|
|
TESTC_(Rowset.GetNextRows(1, rghRow), S_OK);
|
|
TESTC_(Rowset.GetRowData(1, rghRow, (void **)&pData), S_OK);
|
|
|
|
fCheckDefault = CompareData(1, NULL, 1, pData, cBindings, rgBindings, pTable, NULL, PRIMARY, COMPARE_ONLY);
|
|
|
|
fPass = (fCheckDefault == fDefaultExists);
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_FREE(rgBindings)
|
|
Rowset.ReleaseRowData(pData, hAccessor);
|
|
Rowset.ReleaseAccessor(hAccessor);
|
|
|
|
//Rowset.DropRowset();
|
|
|
|
CHECK(pTable->DeleteRows(ALLROWS), S_OK);
|
|
|
|
return fPass;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::VerifyTableUnique
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::VerifyTableUnique
|
|
(
|
|
CTable * pTable,
|
|
BOOL fUniqueExists
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
BOOL fInsertFailed;
|
|
|
|
ASSERT(pTable);
|
|
|
|
// Insert a row using IRowsetChange::InsertRow
|
|
if( FAILED(pTable->Insert(PRIMARY, 1)) )
|
|
return FALSE;
|
|
|
|
// Insert the same row again
|
|
hr = pTable->Insert(PRIMARY, 1);
|
|
fInsertFailed = FAILED(hr);
|
|
|
|
return (fInsertFailed == fUniqueExists);
|
|
}
|
|
|
|
BOOL TCIAlterTable::AlterStringCol2BLOB
|
|
(
|
|
DBTYPE wTargetType,
|
|
BOOL fIsFixed
|
|
)
|
|
{
|
|
TBEGIN
|
|
DBORDINAL ulOrdinal;
|
|
DBORDINAL ulNonLongStrCol = 0;
|
|
DBORDINAL ulLongStrCol = 0;
|
|
CCol schemacol;
|
|
CCol schemacolBLOB;
|
|
CTable * pTable = NULL;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_WTYPE | DBCOLUMNDESCFLAGS_PROPERTIES;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&ColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pSchema->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pSchema->GetColInfo(ulOrdinal, schemacol), S_OK);
|
|
|
|
if( schemacol.GetProviderType() == wTargetType &&
|
|
schemacol.GetIsFixedLength() == fIsFixed &&
|
|
!schemacol.GetIsLong() )
|
|
{
|
|
ulNonLongStrCol = ulOrdinal;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ulNonLongStrCol == 0 )
|
|
{
|
|
odtLog << "Non blob version of " << GetDBTypeName(wTargetType) << " was not found." << ENDL;
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pSchema->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pSchema->GetColInfo(ulOrdinal, schemacolBLOB), S_OK);
|
|
|
|
if( schemacolBLOB.GetProviderType() == wTargetType &&
|
|
schemacolBLOB.GetIsLong() )
|
|
{
|
|
ulLongStrCol = ulOrdinal;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ulLongStrCol == 0 )
|
|
{
|
|
odtLog << "Blob version of " << GetDBTypeName(wTargetType) << " was not found." << ENDL;
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Create a table based on schemacol
|
|
TESTC_(CreateOneColTableWithProps(&pTable, &schemacol, 0, NULL), S_OK);
|
|
|
|
TESTC_(SetChangeColInfo(&schemacolBLOB), S_OK);
|
|
|
|
ColumnDesc.wType = schemacolBLOB.GetProviderType();
|
|
|
|
// Set FixedLength FALSE
|
|
// Set IsLong TRUE
|
|
::SetProperty(DBPROP_COL_FIXEDLENGTH, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(VARIANT_FALSE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
::SetProperty(DBPROP_COL_ISLONG, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(VARIANT_TRUE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
COMPARE(VerifyAlterColumn(1, dwColumnDescFlags, &ColumnDesc, pTable), TRUE);
|
|
|
|
CLEANUP:
|
|
|
|
FreeProperties(&ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::TCAlterCompareDBID
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIAlterTable::TCAlterCompareDBID
|
|
(
|
|
DBID * pdbid1,
|
|
DBID * pdbid2
|
|
)
|
|
{
|
|
BOOL fRes = FALSE;
|
|
|
|
ASSERT( pdbid1 && pdbid2 );
|
|
|
|
if( (pdbid1->eKind == DBKIND_GUID_NAME ||
|
|
pdbid1->eKind == DBKIND_PGUID_NAME ||
|
|
pdbid1->eKind == DBKIND_NAME) &&
|
|
(pdbid2->eKind == DBKIND_GUID_NAME ||
|
|
pdbid2->eKind == DBKIND_PGUID_NAME ||
|
|
pdbid2->eKind == DBKIND_NAME) )
|
|
{
|
|
// just compare the name portion
|
|
TESTC_(CompareID(&fRes, (pdbid1->uName.pwszName),
|
|
(pdbid2->uName.pwszName), NULL), S_OK);
|
|
return fRes;
|
|
}
|
|
else
|
|
{
|
|
fRes = CompareDBID(*pdbid1, *pdbid2);
|
|
}
|
|
|
|
CLEANUP:
|
|
return fRes;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::Thread_AlterTable
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
ULONG TCIAlterTable::Thread_AlterTable(void* pv)
|
|
{
|
|
THREAD_BEGIN
|
|
|
|
//Thread Stack Variables
|
|
TCIAlterTable * pThis = (TCIAlterTable*)THREAD_FUNC;
|
|
HRESULT * phrres = (HRESULT *)THREAD_ARG1;
|
|
DBID * pTableID = (DBID *)THREAD_ARG2;
|
|
DBID * pNewTableID = (DBID *)THREAD_ARG3;
|
|
|
|
ASSERT(pThis && phrres && pTableID && pNewTableID);
|
|
|
|
ThreadSwitch(); //Let the other thread(s) catch up
|
|
|
|
*phrres = pThis->AlterTable(pTableID, pNewTableID);
|
|
|
|
ThreadSwitch(); //Let the other thread(s) catch up
|
|
|
|
THREAD_RETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIAlterTable::Thread_AlterColumn
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
ULONG TCIAlterTable::Thread_AlterColumn(void* pv)
|
|
{
|
|
THREAD_BEGIN
|
|
|
|
//Thread Stack Variables
|
|
TCIAlterTable * pThis = (TCIAlterTable*)THREAD_FUNC;
|
|
DBORDINAL ulOrdinal = (DBORDINAL)THREAD_ARG1;
|
|
DBID * pColumnID = (DBID *)THREAD_ARG2;
|
|
|
|
ASSERT(pThis && pColumnID);
|
|
|
|
ThreadSwitch(); //Let the other thread(s) catch up
|
|
|
|
COMPARE(pThis->VerifyAlterColumnName(ulOrdinal, pColumnID), TRUE);
|
|
|
|
ThreadSwitch(); //Let the other thread(s) catch up
|
|
|
|
THREAD_RETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAlterTable)
|
|
//*-----------------------------------------------------------------------
|
|
// @class TestCases for AlterTable method
|
|
//
|
|
class TCAlterTable : public TCIAlterTable {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAlterTable,TCIAlterTable);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Connect with DBPROP_INIT_MODE requesting read only access. Verify AlterTable return DB_SEC_E_PERMISSIONDENIED
|
|
int Variation_1();
|
|
// @cmember Use AlterTable to change name of view
|
|
int Variation_2();
|
|
// @cmember Use Alter Table to change name of non-table types. Try data type and column names
|
|
int Variation_3();
|
|
// @cmember Use AlterTable when command are active and there are open rowsets, though not on the table to be altered.
|
|
int Variation_4();
|
|
// @cmember Call AlterTable when an updatable rowset is open on the table to be altered
|
|
int Variation_5();
|
|
// @cmember Call AlterTable when a FO/RO rowset is open on the table to be altered
|
|
int Variation_6();
|
|
// @cmember pTableID is NULL. Verify E_INVALIDARG
|
|
int Variation_7();
|
|
// @cmember cPropertySets = 1 and rgPropertySet is NULL. Verify E_INVALIDARG
|
|
int Variation_8();
|
|
// @cmember In rgPropertySets, cProperties = 1 and rgProperties is NULL. Verify E_INVALIDARG
|
|
int Variation_9();
|
|
// @cmember pTableID does not exist. Verify DB_E_NOTABLE
|
|
int Variation_10();
|
|
// @cmember pTableID is a null string. Verify DB_E_NOTABLE
|
|
int Variation_11();
|
|
// @cmember pTableID is an empty string. Verify DB_E_NOTABLE
|
|
int Variation_12();
|
|
// @cmember pTableID has an invalid DBKIND. Verify DB_E_NOTABLE
|
|
int Variation_13();
|
|
// @cmember pNewTableID already exists. Verify DB_E_DUPLICATETABLEID.
|
|
int Variation_14();
|
|
// @cmember pNewTableID is a null string. Verify DB_E_BADTABLEID.
|
|
int Variation_15();
|
|
// @cmember pNewTableID is an empty string. Verify DB_E_BADTABLEID
|
|
int Variation_16();
|
|
// @cmember pNewTableID contains invalid characters for a table id. Verify DB_E_BADTABLEID.
|
|
int Variation_17();
|
|
// @cmember valid pTableID. pNewTableID is NULL, cPropertySets =0, rgPropertySets is NULL. Verify S_OK and no-op.
|
|
int Variation_18();
|
|
// @cmember valid pTableID, pNewTableID = pTableID, cPropertySets=0, rgPropertySets=NULL. Verify S_OK.
|
|
int Variation_19();
|
|
// @cmember Use fully qualified pTableID
|
|
int Variation_20();
|
|
// @cmember Use quoted pTableID
|
|
int Variation_21();
|
|
// @cmember valid pTableID, valid pNewTableID, cPropertySets=0, rgPropertySets=NULL. Verify pTableID no longer exists and pNewTableID exists.
|
|
int Variation_22();
|
|
// @cmember Create temp table. Alter Table to optionally unset property
|
|
int Variation_23();
|
|
// @cmember Create temp table. Alter table to unset that property using REQUIRED option
|
|
int Variation_24();
|
|
// @cmember Create normal table. Alter table to set TEMPTABLE property using REQUIRED option.
|
|
int Variation_25();
|
|
// @cmember Create normal table. Alter table to set TEMPTABLE property using OPTIONAL option.
|
|
int Variation_26();
|
|
// @cmember Request a non TABLE property group with OPTIONAL flag. Verify DB_S_ERRORSOCCURRED.
|
|
int Variation_27();
|
|
// @cmember Request a non TABLE property group with REQUIRED flag. Verify DB_E_ERRORSOCCURRED.
|
|
int Variation_28();
|
|
// @cmember Request a property OPTIONAL where the type in vValue of the DBPROP structure did not match the type of the property. Verify DB_S_ERRORSOCCURRED.
|
|
int Variation_29();
|
|
// @cmember Request a property REQUIRED where the type in vValue of the DBPROP structure did not match the type of the property. Verify DB_E_ERRORSOCCURRED.
|
|
int Variation_30();
|
|
// @cmember Request DBPROP_TBL_TEMPTABLE with vValue type = VT_EMPTY. Verify success.
|
|
int Variation_31();
|
|
// @cmember cPropertySets = 0, rgPropertySets not null. Verify rgPropertySets is ignored.
|
|
int Variation_32();
|
|
// @cmember pNewTableID contains invalid starting characters for a tableid. Verify DB_E_BADTABLEID
|
|
int Variation_33();
|
|
// @cmember pNewTableID exceeds maximum table name length. Verify DB_E_BADTABLEID.
|
|
int Variation_34();
|
|
// @cmember Request bad property option. Verify DB_E_ERRORSOCCURRED
|
|
int Variation_35();
|
|
// @cmember Request, optional, an invalid value of TEMPTABLE
|
|
int Variation_36();
|
|
// @cmember Request, required, an invalid value of TEMPTABLE
|
|
int Variation_37();
|
|
// @cmember Optional prop, colid was not DB_NULLID. Verify DB_S_ERRORSOCCURRED
|
|
int Variation_38();
|
|
// @cmember Required prop, colid was not DB_NULLID. Verify DB_E_ERRORSOCCURRED
|
|
int Variation_39();
|
|
// @cmember Use AlterTable to change table name. Verify using TABLES schema rowset
|
|
int Variation_40();
|
|
// @cmember Mult Threads changing table id. Verify that only one thread succeeds.
|
|
int Variation_43();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAlterTable)
|
|
#define THE_CLASS TCAlterTable
|
|
BEG_TEST_CASE(TCAlterTable, TCIAlterTable, L"TestCases for AlterTable method")
|
|
TEST_VARIATION(1, L"Connect with DBPROP_INIT_MODE requesting read only access. Verify AlterTable return DB_SEC_E_PERMISSIONDENIED")
|
|
TEST_VARIATION(2, L"Use AlterTable to change name of view")
|
|
TEST_VARIATION(3, L"Use Alter Table to change name of non-table types. Try data type and column names")
|
|
TEST_VARIATION(4, L"Use AlterTable when command are active and there are open rowsets, though not on the table to be altered.")
|
|
TEST_VARIATION(5, L"Call AlterTable when an updatable rowset is open on the table to be altered")
|
|
TEST_VARIATION(6, L"Call AlterTable when a FO/RO rowset is open on the table to be altered")
|
|
TEST_VARIATION(7, L"pTableID is NULL. Verify E_INVALIDARG")
|
|
TEST_VARIATION(8, L"cPropertySets = 1 and rgPropertySet is NULL. Verify E_INVALIDARG")
|
|
TEST_VARIATION(9, L"In rgPropertySets, cProperties = 1 and rgProperties is NULL. Verify E_INVALIDARG")
|
|
TEST_VARIATION(10, L"pTableID does not exist. Verify DB_E_NOTABLE")
|
|
TEST_VARIATION(11, L"pTableID is a null string. Verify DB_E_NOTABLE")
|
|
TEST_VARIATION(12, L"pTableID is an empty string. Verify DB_E_NOTABLE")
|
|
TEST_VARIATION(13, L"pTableID has an invalid DBKIND. Verify DB_E_NOTABLE")
|
|
TEST_VARIATION(14, L"pNewTableID already exists. Verify DB_E_DUPLICATETABLEID.")
|
|
TEST_VARIATION(15, L"pNewTableID is a null string. Verify DB_E_BADTABLEID.")
|
|
TEST_VARIATION(16, L"pNewTableID is an empty string. Verify DB_E_BADTABLEID")
|
|
TEST_VARIATION(17, L"pNewTableID contains invalid characters for a table id. Verify DB_E_BADTABLEID.")
|
|
TEST_VARIATION(18, L"valid pTableID. pNewTableID is NULL, cPropertySets =0, rgPropertySets is NULL. Verify S_OK and no-op.")
|
|
TEST_VARIATION(19, L"valid pTableID, pNewTableID = pTableID, cPropertySets=0, rgPropertySets=NULL. Verify S_OK.")
|
|
TEST_VARIATION(20, L"Use fully qualified pTableID")
|
|
TEST_VARIATION(21, L"Use quoted pTableID")
|
|
TEST_VARIATION(22, L"valid pTableID, valid pNewTableID, cPropertySets=0, rgPropertySets=NULL. Verify pTableID no longer exists and pNewTableID exists.")
|
|
TEST_VARIATION(23, L"Create temp table. Alter Table to optionally unset property")
|
|
TEST_VARIATION(24, L"Create temp table. Alter table to unset that property using REQUIRED option")
|
|
TEST_VARIATION(25, L"Create normal table. Alter table to set TEMPTABLE property using REQUIRED option.")
|
|
TEST_VARIATION(26, L"Create normal table. Alter table to set TEMPTABLE property using OPTIONAL option.")
|
|
TEST_VARIATION(27, L"Request a non TABLE property group with OPTIONAL flag. Verify DB_S_ERRORSOCCURRED.")
|
|
TEST_VARIATION(28, L"Request a non TABLE property group with REQUIRED flag. Verify DB_E_ERRORSOCCURRED.")
|
|
TEST_VARIATION(29, L"Request a property OPTIONAL where the type in vValue of the DBPROP structure did not match the type of the property. Verify DB_S_ERRORSOCCURRED.")
|
|
TEST_VARIATION(30, L"Request a property REQUIRED where the type in vValue of the DBPROP structure did not match the type of the property. Verify DB_E_ERRORSOCCURRED.")
|
|
TEST_VARIATION(31, L"Request DBPROP_TBL_TEMPTABLE with vValue type = VT_EMPTY. Verify success.")
|
|
TEST_VARIATION(32, L"cPropertySets = 0, rgPropertySets not null. Verify rgPropertySets is ignored.")
|
|
TEST_VARIATION(33, L"pNewTableID contains invalid starting characters for a tableid. Verify DB_E_BADTABLEID")
|
|
TEST_VARIATION(34, L"pNewTableID exceeds maximum table name length. Verify DB_E_BADTABLEID.")
|
|
TEST_VARIATION(35, L"Request bad property option. Verify DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(36, L"Request, optional, an invalid value of TEMPTABLE")
|
|
TEST_VARIATION(37, L"Request, required, an invalid value of TEMPTABLE")
|
|
TEST_VARIATION(38, L"Optional prop, colid was not DB_NULLID. Verify DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(39, L"Required prop, colid was not DB_NULLID. Verify DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(40, L"Use AlterTable to change table name. Verify using TABLES schema rowset")
|
|
TEST_VARIATION(43, L"Mult Threads changing table id. Verify that only one thread succeeds.")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAlterColumn)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Test Cases for AlterColumn method
|
|
//
|
|
class TCAlterColumn : public TCIAlterTable {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAlterColumn,TCIAlterTable);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Connect with DBPROP_INIT_MODE read only access. Verify DB_SEC_E_PERMISSIONDENIED when altering a column
|
|
int Variation_1();
|
|
// @cmember Try to use AlterColumn to change a table name. Verify failure
|
|
int Variation_2();
|
|
// @cmember Call AlterColumn with multiple commands active which have open rowsets, though not on the table to be altered.
|
|
int Variation_3();
|
|
// @cmember Use AlterColumn when a rowset is open on the table to be altered. Verify DB_E_TABLEINUSE, or if successful, verify DB_S_COLUMNSCHANGE on restart position
|
|
int Variation_4();
|
|
// @cmember Use AlterColumn when a FO/RO rowset is open on the table to be altered. Verify DB_E_TABLEINUSE, or if successful, verify DB_S_COLUMNSCHANGE on restart position
|
|
int Variation_5();
|
|
// @cmember pTableID is NULL. Verify E_INVALIDARG.
|
|
int Variation_6();
|
|
// @cmember pColumnID is NULL. Verify E_INVALIDARG
|
|
int Variation_7();
|
|
// @cmember pColumnDesc is NULL. Verify E_INVALIDARG.
|
|
int Variation_8();
|
|
// @cmember pTableID does not exist. Verify DB_E_NOTABLE
|
|
int Variation_9();
|
|
// @cmember pColumnID does not exist. Verify DB_E_NOCOLUMN
|
|
int Variation_10();
|
|
// @cmember pTableID is a null string. Verify DB_E_NOTABLE
|
|
int Variation_11();
|
|
// @cmember pTableID is an empty string. Verify DB_E_NOTABLE
|
|
int Variation_12();
|
|
// @cmember pTableID has invalid DBKIND. Verify DB_E_NOTABLE
|
|
int Variation_13();
|
|
// @cmember pColumnID is a null string. Verify DB_E_NOCOLUMN
|
|
int Variation_14();
|
|
// @cmember pColumnID is an empty string. Verify DB_E_NOCOLUMN.
|
|
int Variation_15();
|
|
// @cmember pColumnID has invalid DBKIND. Verify DB_E_NOCOLUMN.
|
|
int Variation_16();
|
|
// @cmember ColumnDescFlags was not supported. Verify DB_E_NOTSUPPORTED
|
|
int Variation_17();
|
|
// @cmember Invalid ColumnDescFlags. Verify DB_E_NOTSUPPORTED.
|
|
int Variation_18();
|
|
// @cmember pColumnDesc contains an existing column id. Verify DB_E_DUPLICATECOLUMNID.
|
|
int Variation_19();
|
|
// @cmember pColumnDesc contains invalid DBKIND. Verify DB_E_BADCOLUMNID.
|
|
int Variation_20();
|
|
// @cmember pColumnDesc contains empty string. Verify DB_E_BADCOLUMNID.
|
|
int Variation_21();
|
|
// @cmember pColumnDesc contains NULL string. Verify DB_E_BADCOLUMNID
|
|
int Variation_22();
|
|
// @cmember pColumnDesc contains an invalid precision, overflow and underflow. Verify DB_E_BADPRECISION
|
|
int Variation_23();
|
|
// @cmember pColumnDesc contains an invalid scale, both overflow and underflow. Verify DB_E_BADSCALE.
|
|
int Variation_24();
|
|
// @cmember pColumnDesc contains an invalid type name. Verify DB_E_BADTYPE
|
|
int Variation_25();
|
|
// @cmember pColumnDesc contains an invalid DBTYPE
|
|
int Variation_26();
|
|
// @cmember In pColumnDesc, cPropertySets > 0 and rgPropertySets is null. Verify E_INVALIDARG.
|
|
int Variation_27();
|
|
// @cmember DBCOLUMNDESCFLAG_DBCID. Change ID of columns
|
|
int Variation_28();
|
|
// @cmember DBCOLUMNDESCFLAGS_COLSIZE. Change column size of columns
|
|
int Variation_29();
|
|
// @cmember DBCOLUMNDESCFLAGS_PRECISION. Change precision of columns.
|
|
int Variation_30();
|
|
// @cmember DBCOLUMNDESCFLAGS_SCALE. Change scale of columns
|
|
int Variation_31();
|
|
// @cmember DBCOLUMNDESCFLAG_CLSID. Change clsid of columns.
|
|
int Variation_32();
|
|
// @cmember DBCOLUMNDESCFLAGS_WTYPE. Change dbtype of columns.
|
|
int Variation_33();
|
|
// @cmember DBCOLUMNDESC_TYPENAME. Change typename of columns
|
|
int Variation_34();
|
|
// @cmember DBCOLUMNDESC_ITYPEINFO. Change type info of columns.
|
|
int Variation_35();
|
|
// @cmember DBPROP_COL_FIXEDLENGTH
|
|
int Variation_36();
|
|
// @cmember DBPROP_COL_ISLONG
|
|
int Variation_37();
|
|
// @cmember DBPROP_COL_NULLABLE
|
|
int Variation_38();
|
|
// @cmember DBPROP_COL_DESCRIPTION
|
|
int Variation_39();
|
|
// @cmember DBPROP_COL_UNIQUE
|
|
int Variation_40();
|
|
// @cmember DBPROP_COLUMNLCID
|
|
int Variation_41();
|
|
// @cmember DBPROP_COL_PRIMARYKEY
|
|
int Variation_42();
|
|
// @cmember DBPROP_COL_DEFAULT
|
|
int Variation_43();
|
|
// @cmember DBPROP_COL_AUTOINCREMENT
|
|
int Variation_44();
|
|
// @cmember Multiple attribute change
|
|
int Variation_45();
|
|
// @cmember Test atomicity. Valid new ID but one other invalid attribute
|
|
int Variation_46();
|
|
// @cmember Test atomicity. Drop UNIQUE constraint and change to invalid type
|
|
int Variation_47();
|
|
// @cmember In an element of rgPropertySets, cProperties was > 0 but rgProperties was not null
|
|
int Variation_48();
|
|
// @cmember Drop multiple constraints
|
|
int Variation_49();
|
|
// @cmember Add multiple constraints
|
|
int Variation_50();
|
|
// @cmember Test atomicity. Alter column id along with unsupported ColumnDescFlag
|
|
int Variation_51();
|
|
// @cmember Request BLOB using DBPROP_COL_ISLONG,FIXEDLENGTH
|
|
int Variation_52();
|
|
// @cmember Request DBPROP_COL_NULLABLE on non-nullable type. Verify error
|
|
int Variation_53();
|
|
// @cmember Request PRIMARYKEY and UNIQUE constraints - verify error
|
|
int Variation_54();
|
|
// @cmember Request AutoInc on non AUTO_UNIQUE_VALUE. Verify error
|
|
int Variation_55();
|
|
// @cmember Request ISLONG with FIXEDLENGTH true. Verify Error
|
|
int Variation_56();
|
|
// @cmember Threads. Test one thread altering a distinct col. Verify each thread succeeds.
|
|
int Variation_57();
|
|
// @cmember ColumnDescFlags is 0. Verify no-op
|
|
int Variation_58();
|
|
// @cmember Change Column ID and use new Column ID in select stmt
|
|
int Variation_59();
|
|
// @cmember Change column id to invalid keyword. Verify Error
|
|
int Variation_60();
|
|
// @cmember Combination E_INVALIDARG conditiions
|
|
int Variation_61();
|
|
// @cmember WTYPE and TYPENAME mismatch. Verify DB_E_BADTYPE
|
|
int Variation_62();
|
|
// @cmember SupportedTXNDDL
|
|
int Variation_63();
|
|
// @cmember Bad prop option
|
|
int Variation_64();
|
|
// @cmember Non column prop set REQUIRED
|
|
int Variation_65();
|
|
// @cmember Non column prop set OPTIONAL
|
|
int Variation_66();
|
|
// @cmember Mismatch in property vt type. REQUIRED
|
|
int Variation_67();
|
|
// @cmember Mismatch in property vt type. OPTIONAL
|
|
int Variation_68();
|
|
// @cmember Invalid property value. REQUIRED
|
|
int Variation_69();
|
|
// @cmember Invalid property value. OPTIONAL
|
|
int Variation_70();
|
|
// @cmember colid was not DB_NULLID. OPTIONAL
|
|
int Variation_71();
|
|
// @cmember colid was not DB_NULLID. REQUIRED
|
|
int Variation_72();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAlterColumn)
|
|
#define THE_CLASS TCAlterColumn
|
|
BEG_TEST_CASE(TCAlterColumn, TCIAlterTable, L"Test Cases for AlterColumn method")
|
|
TEST_VARIATION(1, L"Connect with DBPROP_INIT_MODE read only access. Verify DB_SEC_E_PERMISSIONDENIED when altering a column")
|
|
TEST_VARIATION(2, L"Try to use AlterColumn to change a table name. Verify failure")
|
|
TEST_VARIATION(3, L"Call AlterColumn with multiple commands active which have open rowsets, though not on the table to be altered.")
|
|
TEST_VARIATION(4, L"Use AlterColumn when a rowset is open on the table to be altered. Verify DB_E_TABLEINUSE, or if successful, verify DB_S_COLUMNSCHANGE on restart position")
|
|
TEST_VARIATION(5, L"Use AlterColumn when a FO/RO rowset is open on the table to be altered. Verify DB_E_TABLEINUSE, or if successful, verify DB_S_COLUMNSCHANGE on restart position")
|
|
TEST_VARIATION(6, L"pTableID is NULL. Verify E_INVALIDARG.")
|
|
TEST_VARIATION(7, L"pColumnID is NULL. Verify E_INVALIDARG")
|
|
TEST_VARIATION(8, L"pColumnDesc is NULL. Verify E_INVALIDARG.")
|
|
TEST_VARIATION(9, L"pTableID does not exist. Verify DB_E_NOTABLE")
|
|
TEST_VARIATION(10, L"pColumnID does not exist. Verify DB_E_NOCOLUMN")
|
|
TEST_VARIATION(11, L"pTableID is a null string. Verify DB_E_NOTABLE")
|
|
TEST_VARIATION(12, L"pTableID is an empty string. Verify DB_E_NOTABLE")
|
|
TEST_VARIATION(13, L"pTableID has invalid DBKIND. Verify DB_E_NOTABLE")
|
|
TEST_VARIATION(14, L"pColumnID is a null string. Verify DB_E_NOCOLUMN")
|
|
TEST_VARIATION(15, L"pColumnID is an empty string. Verify DB_E_NOCOLUMN.")
|
|
TEST_VARIATION(16, L"pColumnID has invalid DBKIND. Verify DB_E_NOCOLUMN.")
|
|
TEST_VARIATION(17, L"ColumnDescFlags was not supported. Verify DB_E_NOTSUPPORTED")
|
|
TEST_VARIATION(18, L"Invalid ColumnDescFlags. Verify DB_E_NOTSUPPORTED.")
|
|
TEST_VARIATION(19, L"pColumnDesc contains an existing column id. Verify DB_E_DUPLICATECOLUMNID.")
|
|
TEST_VARIATION(20, L"pColumnDesc contains invalid DBKIND. Verify DB_E_BADCOLUMNID.")
|
|
TEST_VARIATION(21, L"pColumnDesc contains empty string. Verify DB_E_BADCOLUMNID.")
|
|
TEST_VARIATION(22, L"pColumnDesc contains NULL string. Verify DB_E_BADCOLUMNID")
|
|
TEST_VARIATION(23, L"pColumnDesc contains an invalid precision, overflow and underflow. Verify DB_E_BADPRECISION")
|
|
TEST_VARIATION(24, L"pColumnDesc contains an invalid scale, both overflow and underflow. Verify DB_E_BADSCALE.")
|
|
TEST_VARIATION(25, L"pColumnDesc contains an invalid type name. Verify DB_E_BADTYPE")
|
|
TEST_VARIATION(26, L"pColumnDesc contains an invalid DBTYPE")
|
|
TEST_VARIATION(27, L"In pColumnDesc, cPropertySets > 0 and rgPropertySets is null. Verify E_INVALIDARG.")
|
|
TEST_VARIATION(28, L"DBCOLUMNDESCFLAG_DBCID. Change ID of columns")
|
|
TEST_VARIATION(29, L"DBCOLUMNDESCFLAGS_COLSIZE. Change column size of columns")
|
|
TEST_VARIATION(30, L"DBCOLUMNDESCFLAGS_PRECISION. Change precision of columns.")
|
|
TEST_VARIATION(31, L"DBCOLUMNDESCFLAGS_SCALE. Change scale of columns")
|
|
TEST_VARIATION(32, L"DBCOLUMNDESCFLAG_CLSID. Change clsid of columns.")
|
|
TEST_VARIATION(33, L"DBCOLUMNDESCFLAGS_WTYPE. Change dbtype of columns.")
|
|
TEST_VARIATION(34, L"DBCOLUMNDESC_TYPENAME. Change typename of columns")
|
|
TEST_VARIATION(35, L"DBCOLUMNDESC_ITYPEINFO. Change type info of columns.")
|
|
TEST_VARIATION(36, L"DBPROP_COL_FIXEDLENGTH")
|
|
TEST_VARIATION(37, L"DBPROP_COL_ISLONG")
|
|
TEST_VARIATION(38, L"DBPROP_COL_NULLABLE")
|
|
TEST_VARIATION(39, L"DBPROP_COL_DESCRIPTION")
|
|
TEST_VARIATION(40, L"DBPROP_COL_UNIQUE")
|
|
TEST_VARIATION(41, L"DBPROP_COLUMNLCID")
|
|
TEST_VARIATION(42, L"DBPROP_COL_PRIMARYKEY")
|
|
TEST_VARIATION(43, L"DBPROP_COL_DEFAULT")
|
|
TEST_VARIATION(44, L"DBPROP_COL_AUTOINCREMENT")
|
|
TEST_VARIATION(45, L"Multiple attribute change")
|
|
TEST_VARIATION(46, L"Test atomicity. Valid new ID but one other invalid attribute")
|
|
TEST_VARIATION(47, L"Test atomicity. Drop UNIQUE constraint and change to invalid type")
|
|
TEST_VARIATION(48, L"In an element of rgPropertySets, cProperties was > 0 but rgProperties was not null")
|
|
TEST_VARIATION(49, L"Drop multiple constraints")
|
|
TEST_VARIATION(50, L"Add multiple constraints")
|
|
TEST_VARIATION(51, L"Test atomicity. Alter column id along with unsupported ColumnDescFlag")
|
|
TEST_VARIATION(52, L"Request BLOB using DBPROP_COL_ISLONG,FIXEDLENGTH")
|
|
TEST_VARIATION(53, L"Request DBPROP_COL_NULLABLE on non-nullable type. Verify error")
|
|
TEST_VARIATION(54, L"Request PRIMARYKEY and UNIQUE constraints - verify error")
|
|
TEST_VARIATION(55, L"Request AutoInc on non AUTO_UNIQUE_VALUE. Verify error")
|
|
TEST_VARIATION(56, L"Request ISLONG with FIXEDLENGTH true. Verify Error")
|
|
TEST_VARIATION(57, L"Threads. Test one thread altering a distinct col. Verify each thread succeeds.")
|
|
TEST_VARIATION(58, L"ColumnDescFlags is 0. Verify no-op")
|
|
TEST_VARIATION(59, L"Change Column ID and use new Column ID in select stmt")
|
|
TEST_VARIATION(60, L"Change column id to invalid keyword. Verify Error")
|
|
TEST_VARIATION(61, L"Combination E_INVALIDARG conditiions")
|
|
TEST_VARIATION(62, L"WTYPE and TYPENAME mismatch. Verify DB_E_BADTYPE")
|
|
TEST_VARIATION(63, L"SupportedTXNDDL")
|
|
TEST_VARIATION(64, L"Bad prop option")
|
|
TEST_VARIATION(65, L"Non column prop set REQUIRED")
|
|
TEST_VARIATION(66, L"Non column prop set OPTIONAL")
|
|
TEST_VARIATION(67, L"Mismatch in property vt type. REQUIRED")
|
|
TEST_VARIATION(68, L"Mismatch in property vt type. OPTIONAL")
|
|
TEST_VARIATION(69, L"Invalid property value. REQUIRED")
|
|
TEST_VARIATION(70, L"Invalid property value. OPTIONAL")
|
|
TEST_VARIATION(71, L"colid was not DB_NULLID. OPTIONAL")
|
|
TEST_VARIATION(72, L"colid was not DB_NULLID. REQUIRED")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCZombie)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Test the Zombie states of IAlterTable
|
|
//
|
|
class TCZombie : public CTransaction {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCZombie,CTransaction);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember ABORT with fRetaining TRUE
|
|
int Variation_1();
|
|
// @cmember ABORT with fRetaining FALSE
|
|
int Variation_2();
|
|
// @cmember COMMIT with fRetaining TRUE
|
|
int Variation_3();
|
|
// @cmember COMMIT with fRetaining FALSE
|
|
int Variation_4();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCZombie)
|
|
#define THE_CLASS TCZombie
|
|
BEG_TEST_CASE(TCZombie, CTransaction, L"Test the Zombie states of IAlterTable")
|
|
TEST_VARIATION(1, L"ABORT with fRetaining TRUE")
|
|
TEST_VARIATION(2, L"ABORT with fRetaining FALSE")
|
|
TEST_VARIATION(3, L"COMMIT with fRetaining TRUE")
|
|
TEST_VARIATION(4, L"COMMIT with fRetaining FALSE")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level initialization routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleInit(CThisTestModule * pThisTestModule)
|
|
{
|
|
return CommonModuleInit(pThisTestModule, IID_IAlterTable);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level termination routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleTerminate(CThisTestModule * pThisTestModule)
|
|
{
|
|
return CommonModuleTerminate(pThisTestModule);
|
|
}
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Test Case Section
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// }} END_DECLARE_TEST_CASES()
|
|
|
|
// {{ TCW_TESTMODULE(ThisModule)
|
|
TEST_MODULE(3, ThisModule, gwszModuleDescrip)
|
|
TEST_CASE(1, TCAlterTable)
|
|
TEST_CASE(2, TCAlterColumn)
|
|
TEST_CASE(3, TCZombie)
|
|
END_TEST_MODULE()
|
|
// }} TCW_TESTMODULE_END
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAlterTable)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAlterTable - TestCases for AlterTable method
|
|
//| Created: 8/6/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAlterTable::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCIAlterTable::Init())
|
|
// }}
|
|
{
|
|
// TO DO: Add your own code here
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Connect with DBPROP_INIT_MODE requesting read only access. Verify AlterTable return DB_SEC_E_PERMISSIONDENIED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_1()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
IUnknown * pUnkReadSession = NULL;
|
|
IAlterTable * pIAlterTable = NULL;
|
|
|
|
// Try to obtain a read only session
|
|
if( !GetReadOnlySession(&pUnkReadSession) )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC(VerifyInterface(pUnkReadSession, IID_IAlterTable, SESSION_INTERFACE,
|
|
(IUnknown**)&pIAlterTable));
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
TESTC_(pIAlterTable->AlterTable(&(m_pTable->GetTableID()), &NewTableID, 0 , NULL), DB_SEC_E_PERMISSIONDENIED);
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pUnkReadSession);
|
|
SAFE_RELEASE(pIAlterTable);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use AlterTable to change name of view
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBID ViewID;
|
|
DBID NewTableID;
|
|
HRESULT hr;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(m_pTable->ExecuteCommand(CREATE_VIEW, IID_NULL), S_OK);
|
|
|
|
ViewID.eKind = DBKIND_NAME;
|
|
ViewID.uName.pwszName = wcsDuplicate(m_pTable->GetViewName());
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
TESTC(hr = VerifyAlterTable(&ViewID, &NewTableID));
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
m_pTable->SetViewName(NewTableID.uName.pwszName);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TESTC_(m_pTable->ExecuteCommand(DROP_VIEW, IID_NULL), S_OK);
|
|
|
|
ReleaseDBID(&ViewID, FALSE);
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use Alter Table to change name of non-table types. Try data type and column names
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_3()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
CCol TempCol;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC_(m_pTable->GetColInfo(1, TempCol), S_OK);
|
|
|
|
TESTC_(AlterTable(TempCol.GetColID(), &NewTableID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use AlterTable when command are active and there are open rowsets, though not on the table to be altered.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CRowset RowsetA;
|
|
CRowset RowsetB;
|
|
IRowset * pIRowsetA = NULL;
|
|
IRowset * pIRowsetB = NULL;
|
|
DBID NewTableID;
|
|
|
|
//Create a couple rowsets using ICommand::Execute
|
|
TESTC_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowsetA), S_OK);
|
|
TESTC_(RowsetB.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowsetB), S_OK);
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC(VerifyAlterTable(&(m_pTable->GetTableID()), &NewTableID));
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIRowsetA);
|
|
SAFE_RELEASE(pIRowsetB);
|
|
|
|
RestoreTableID(&NewTableID);
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call AlterTable when an updatable rowset is open on the table to be altered
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_5()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CRowset RowsetA;
|
|
IRowset * pIRowset = NULL;
|
|
DBID NewTableID;
|
|
|
|
//Create an updatable rowset using ICommand::Execute
|
|
RowsetA.SetTable(m_pTable, DELETETABLE_NO);
|
|
RowsetA.SetSettableProperty(DBPROP_IRowsetLocate, DBPROPSET_ROWSET);
|
|
RowsetA.SetSettableProperty(DBPROP_IRowsetChange, DBPROPSET_ROWSET);
|
|
|
|
TESTC_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowset), S_OK);
|
|
TESTC(DefaultObjectTesting(pIRowset, ROWSET_INTERFACE));
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TEST2C_(hr = AlterTable(&(m_pTable->GetTableID()), &NewTableID), S_OK, DB_E_TABLEINUSE);
|
|
if( S_OK == hr )
|
|
{
|
|
TESTC(CheckAlterTableID(&m_pTable->GetTableID(), &NewTableID));
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
|
|
if( S_OK == hr )
|
|
{
|
|
RestoreTableID(&NewTableID);
|
|
}
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call AlterTable when a FO/RO rowset is open on the table to be altered
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_6()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CRowset RowsetA;
|
|
IRowset * pIRowset = NULL;
|
|
DBID NewTableID;
|
|
|
|
//Create a rowset using ICommand::Execute
|
|
RowsetA.SetTable(m_pTable, DELETETABLE_NO);
|
|
TESTC_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowset), S_OK);
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TEST2C_(hr = AlterTable(&(m_pTable->GetTableID()), &NewTableID), S_OK, DB_E_TABLEINUSE);
|
|
if( S_OK == hr )
|
|
{
|
|
TESTC(CheckAlterTableID(&m_pTable->GetTableID(), &NewTableID));
|
|
}
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
|
|
if( S_OK == hr )
|
|
{
|
|
RestoreTableID(&NewTableID);
|
|
}
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is NULL. Verify E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_7()
|
|
{
|
|
return CHECK(AlterTable(NULL, NULL), E_INVALIDARG);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cPropertySets = 1 and rgPropertySet is NULL. Verify E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_8()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
|
|
TESTC_(DuplicateDBID(m_pTable->GetTableID(), &NewTableID), S_OK);
|
|
TESTC_(AlterTable(&(m_pTable->GetTableID()), &NewTableID, 1, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc In rgPropertySets, cProperties = 1 and rgProperties is NULL. Verify E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
DBPROPSET PropertySet;
|
|
|
|
PropertySet.cProperties = 1;
|
|
PropertySet.guidPropertySet = DBPROPSET_TABLE;
|
|
PropertySet.rgProperties = NULL;
|
|
|
|
TESTC_(DuplicateDBID(m_pTable->GetTableID(), &NewTableID), S_OK);
|
|
TESTC_(AlterTable(&(m_pTable->GetTableID()), &NewTableID, 1, &PropertySet), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID does not exist. Verify DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_10()
|
|
{
|
|
TBEGIN
|
|
DBID NonExistentTableID;
|
|
DBID NewTableID;
|
|
|
|
TESTC_(MakeNewTableID(&NonExistentTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
TESTC_(AlterTable(&NonExistentTableID, &NewTableID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NonExistentTableID, FALSE);
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is a null string. Verify DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_11()
|
|
{
|
|
TBEGIN
|
|
DBID NullID;
|
|
DBID NewTableID;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&NullID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
SAFE_FREE(NullID.uName.pwszName);
|
|
|
|
TESTC_(AlterTable(&NullID, &NewTableID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NullID, FALSE);
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is an empty string. Verify DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_12()
|
|
{
|
|
TBEGIN
|
|
DBID EmptyID;
|
|
DBID NewTableID;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&EmptyID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
if( EmptyID.uName.pwszName )
|
|
EmptyID.uName.pwszName[0] = L'\0';
|
|
|
|
TESTC_(AlterTable(&EmptyID, &NewTableID), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&EmptyID, FALSE);
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID has an invalid DBKIND. Verify DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_13()
|
|
{
|
|
TBEGIN
|
|
LONG eKind;
|
|
DBID TableID;
|
|
DBID NewTableID;
|
|
|
|
TableID = m_pTable->GetTableID();
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
for( eKind = DBKIND_GUID_NAME; eKind <= DBKIND_GUID+1; eKind++ )
|
|
{
|
|
if( eKind == m_lDBIDType )
|
|
continue;
|
|
|
|
TableID.eKind = eKind;
|
|
TESTC_(AlterTable(&TableID, &NewTableID), DB_E_NOTABLE);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
NewTableID.eKind = m_lDBIDType;
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pNewTableID already exists. Verify DB_E_DUPLICATETABLEID.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_14()
|
|
{
|
|
CHECK(AlterTable(&m_pTable->GetTableID(), &g_pTable->GetTableID()), DB_E_DUPLICATETABLEID);
|
|
CHECK(AlterTable(&m_pTable->GetTableID(), &g_pEmptyTable->GetTableID()), DB_E_DUPLICATETABLEID);
|
|
CHECK(AlterTable(&m_pTable->GetTableID(), &g_p1RowTable->GetTableID()), DB_E_DUPLICATETABLEID);
|
|
|
|
return TEST_PASS;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pNewTableID is a null string. Verify DB_E_BADTABLEID.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_15()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
SAFE_FREE(NewTableID.uName.pwszName);
|
|
|
|
TESTC_(AlterTable(&m_pTable->GetTableID(), &NewTableID), DB_E_BADTABLEID);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pNewTableID is an empty string. Verify DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_16()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
if( NewTableID.uName.pwszName )
|
|
NewTableID.uName.pwszName[0] = L'\0';
|
|
|
|
TESTC_(AlterTable(&m_pTable->GetTableID(), &NewTableID), DB_E_BADTABLEID);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pNewTableID contains invalid characters for a table id. Verify DB_E_BADTABLEID.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_17()
|
|
{
|
|
TBEGIN
|
|
ULONG cIter = 0;
|
|
DBID NewTableID;
|
|
HRESULT hr;
|
|
WCHAR * pwszNewTableName = NULL;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME || !m_pwszInvalidTableChars )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
pwszNewTableName = wcsDuplicate(NewTableID.uName.pwszName);
|
|
TESTC(pwszNewTableName != NULL);
|
|
SAFE_FREE(NewTableID.uName.pwszName);
|
|
|
|
for( cIter = 0; cIter < wcslen(m_pwszInvalidTableChars); cIter++ )
|
|
{
|
|
NewTableID.uName.pwszName = wcsDuplicate(pwszNewTableName);
|
|
NewTableID.uName.pwszName[ cIter % wcslen(pwszNewTableName) ] = m_pwszInvalidTableChars[cIter];
|
|
|
|
hr = AlterTable(&m_pTable->GetTableID(), &NewTableID);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
RestoreTableID(&NewTableID);
|
|
}
|
|
TESTC_(hr, DB_E_BADTABLEID);
|
|
|
|
SAFE_FREE(NewTableID.uName.pwszName);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc valid pTableID. pNewTableID is NULL, cPropertySets =0, rgPropertySets is NULL. Verify S_OK and no-op.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_18()
|
|
{
|
|
return VerifyAlterTable(&(m_pTable->GetTableID()), NULL);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc valid pTableID, pNewTableID = pTableID, cPropertySets=0, rgPropertySets=NULL. Verify S_OK.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_19()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
|
|
TESTC_(DuplicateDBID(m_pTable->GetTableID(), &NewTableID), S_OK);
|
|
TESTC(VerifyAlterTable(&(m_pTable->GetTableID()), &NewTableID));
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use fully qualified pTableID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_20()
|
|
{
|
|
TBEGIN
|
|
BOOL fTableFound = FALSE;
|
|
WCHAR * pwszTableName = NULL;
|
|
WCHAR * pwszQualifiedTableName = NULL;
|
|
WCHAR * pwszCatalogName = NULL;
|
|
WCHAR * pwszSchemaName = NULL;
|
|
DBID QualifiedTableID;
|
|
DBID NewTableID;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC_(DuplicateDBID(m_pTable->GetTableID(), &QualifiedTableID), S_OK);
|
|
pwszTableName = QualifiedTableID.uName.pwszName;
|
|
|
|
// Tables schema is not necessarily supported
|
|
if( !GetTableSchemaInfo(m_pTable, pwszTableName ,&fTableFound, &pwszCatalogName, &pwszSchemaName) )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC( fTableFound == TRUE );
|
|
|
|
//Construct a fully Qualified TableName...
|
|
TESTC_(m_pTable->GetQualifiedName(pwszCatalogName, pwszSchemaName,
|
|
pwszTableName, &pwszQualifiedTableName), S_OK);
|
|
SAFE_FREE(QualifiedTableID.uName.pwszName);
|
|
QualifiedTableID.uName.pwszName = pwszQualifiedTableName;
|
|
|
|
TESTC(VerifyAlterTable(&QualifiedTableID, &NewTableID));
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_FREE(pwszCatalogName);
|
|
SAFE_FREE(pwszSchemaName);
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
ReleaseDBID(&QualifiedTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use quoted pTableID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_21()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
WCHAR * pwszQuotedName = NULL;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
if( NewTableID.eKind == DBKIND_NAME )
|
|
{
|
|
|
|
pwszQuotedName = (WCHAR *)PROVIDER_ALLOC(sizeof(WCHAR *)*(wcslen(NewTableID.uName.pwszName)+1));
|
|
TESTC(pwszQuotedName != NULL);
|
|
|
|
swprintf(pwszQuotedName, L"\"%s\"", NewTableID.uName.pwszName);
|
|
|
|
SAFE_FREE(NewTableID.uName.pwszName);
|
|
NewTableID.uName.pwszName = pwszQuotedName;
|
|
}
|
|
|
|
TESTC(VerifyAlterTable(&(m_pTable->GetTableID()), &NewTableID));
|
|
|
|
CLEANUP:
|
|
|
|
RestoreTableID(&NewTableID);
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc valid pTableID, valid pNewTableID, cPropertySets=0, rgPropertySets=NULL. Verify pTableID no longer exists and pNewTableID exists.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_22()
|
|
{
|
|
TBEGIN
|
|
DBID TableID;
|
|
DBID NewTableID;
|
|
size_t rgTableLengths[] =
|
|
{
|
|
1, // one char table name
|
|
2, // two char table name
|
|
m_cchMaxTableName/2, // medium length
|
|
m_cchMaxTableName - 1, // max length - 1
|
|
m_cchMaxTableName // max length
|
|
};
|
|
HRESULT hr;
|
|
BOOL fExists = FALSE;
|
|
ULONG cIter = 0;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
if( m_cchMaxTableName == ~0 )
|
|
{
|
|
// Unknown maximum length
|
|
size_t cchLen = wcslen(m_pTable->GetTableName());
|
|
|
|
rgTableLengths[2] = cchLen/2;
|
|
rgTableLengths[3] = cchLen-1;
|
|
rgTableLengths[4] = cchLen;
|
|
}
|
|
|
|
TESTC_(DuplicateDBID(m_pTable->GetTableID(), &TableID), S_OK);
|
|
|
|
// Try altering the table name to several interesting lengths.
|
|
for( cIter = 0; cIter < NUMELEM(rgTableLengths); cIter++ )
|
|
{
|
|
if( rgTableLengths[cIter] > m_cchMaxTableName )
|
|
continue;
|
|
|
|
hr = MakeNewTableID(&NewTableID, DBKIND_NAME, rgTableLengths[cIter]);
|
|
if( S_FALSE == hr )
|
|
continue;
|
|
|
|
TESTC_(hr, S_OK);
|
|
|
|
TEST(VerifyAlterTable(&TableID, &NewTableID));
|
|
|
|
SAFE_FREE(TableID.uName.pwszName);
|
|
TableID.uName.pwszName = wcsDuplicate(NewTableID.uName.pwszName);
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
RestoreTableID(&TableID);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create temp table. Alter Table to optionally unset property
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_23()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable * pTable = NULL;
|
|
|
|
TEST2C_(hr = CreateTable(&pTable, DBPROP_TBL_TEMPTABLE, (void *)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED), S_OK, S_FALSE);
|
|
|
|
if( hr == S_FALSE )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC(VerifyAlterTableProperties(&pTable->GetTableID(), DBPROP_TBL_TEMPTABLE,
|
|
DBPROPSET_TABLE, (void *)VARIANT_FALSE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL));
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create temp table. Alter table to unset that property using REQUIRED option
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_24()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CTable * pTable = NULL;
|
|
|
|
TEST2C_(hr = CreateTable(&pTable, DBPROP_TBL_TEMPTABLE, (void *)VARIANT_TRUE,
|
|
DBPROPOPTIONS_REQUIRED), S_OK, S_FALSE);
|
|
|
|
if( hr == S_FALSE )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC(VerifyAlterTableProperties(&pTable->GetTableID(), DBPROP_TBL_TEMPTABLE,
|
|
DBPROPSET_TABLE, (void *)VARIANT_FALSE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED));
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create normal table. Alter table to set TEMPTABLE property using REQUIRED option.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_25()
|
|
{
|
|
TBEGIN
|
|
CTable * pTable = NULL;
|
|
|
|
TESTC_(CreateTable(&pTable), S_OK);
|
|
|
|
TESTC(VerifyAlterTableProperties(&pTable->GetTableID(), DBPROP_TBL_TEMPTABLE,
|
|
DBPROPSET_TABLE, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED));
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Create normal table. Alter table to set TEMPTABLE property using OPTIONAL option.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_26()
|
|
{
|
|
TBEGIN
|
|
CTable * pTable = NULL;
|
|
|
|
TESTC_(CreateTable(&pTable), S_OK);
|
|
|
|
TESTC(VerifyAlterTableProperties(&pTable->GetTableID(), DBPROP_TBL_TEMPTABLE,
|
|
DBPROPSET_TABLE, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL));
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request a non TABLE property group with OPTIONAL flag. Verify DB_S_ERRORSOCCURRED.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_27()
|
|
{
|
|
return VerifyNonTableProps(DBPROPOPTIONS_OPTIONAL);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request a non TABLE property group with REQUIRED flag. Verify DB_E_ERRORSOCCURRED.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_28()
|
|
{
|
|
return VerifyNonTableProps(DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request a property OPTIONAL where the type in vValue of the DBPROP structure did not match the type of the property. Verify DB_S_ERRORSOCCURRED.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_29()
|
|
{
|
|
return VerifyAlterInvalidTableProperties(&m_pTable->GetTableID(), DBPROPSTATUS_NOTSET,
|
|
DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE, (void *)1, DBTYPE_I4, DBPROPOPTIONS_OPTIONAL);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request a property REQUIRED where the type in vValue of the DBPROP structure did not match the type of the property. Verify DB_E_ERRORSOCCURRED.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_30()
|
|
{
|
|
return VerifyAlterInvalidTableProperties(&m_pTable->GetTableID(), DBPROPSTATUS_BADVALUE,
|
|
DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE, (void *)L"Foo", DBTYPE_BSTR, DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request DBPROP_TBL_TEMPTABLE with vValue type = VT_EMPTY. Verify success.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_31()
|
|
{
|
|
TBEGIN
|
|
|
|
TESTC(VerifyAlterTableProperties(&m_pTable->GetTableID(), DBPROP_TBL_TEMPTABLE,
|
|
DBPROPSET_TABLE, NULL, DBTYPE_EMPTY, DBPROPOPTIONS_REQUIRED));
|
|
|
|
TESTC(VerifyAlterTableProperties(&m_pTable->GetTableID(), DBPROP_TBL_TEMPTABLE,
|
|
DBPROPSET_TABLE, NULL, DBTYPE_EMPTY, DBPROPOPTIONS_OPTIONAL));
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc cPropertySets = 0, rgPropertySets not null. Verify rgPropertySets is ignored.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_32()
|
|
{
|
|
TBEGIN
|
|
TESTC_(AlterTable(&m_pTable->GetTableID(), NULL, 0, INVALID(DBPROPSET *)), S_OK);
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pNewTableID contains invalid starting characters for a tableid. Verify DB_E_BADTABLEID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_33()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
ULONG cIter = 0;
|
|
DBID NewTableID;
|
|
WCHAR * pwszNewTableName = NULL;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME || !m_pwszInvalidStartingTableChars )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
pwszNewTableName = wcsDuplicate(NewTableID.uName.pwszName);
|
|
TESTC(pwszNewTableName != NULL);
|
|
SAFE_FREE(NewTableID.uName.pwszName);
|
|
|
|
for( cIter = 0; cIter < wcslen(m_pwszInvalidStartingTableChars); cIter++ )
|
|
{
|
|
NewTableID.uName.pwszName = wcsDuplicate(pwszNewTableName);
|
|
NewTableID.uName.pwszName[0] = m_pwszInvalidStartingTableChars[cIter];
|
|
|
|
hr = AlterTable(&m_pTable->GetTableID(), &NewTableID);
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
RestoreTableID(&NewTableID);
|
|
}
|
|
TESTC_(hr, DB_E_BADTABLEID);
|
|
|
|
SAFE_FREE(NewTableID.uName.pwszName);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pNewTableID exceeds maximum table name length. Verify DB_E_BADTABLEID.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_34()
|
|
{
|
|
TBEGIN
|
|
DBID NewTableID;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME || !m_pwszInvalidStartingTableChars )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, m_cchMaxColName+1), S_OK);
|
|
TESTC_(AlterTable(&m_pTable->GetTableID(), &NewTableID), DB_E_BADTABLEID);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request bad property option. Verify DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_35()
|
|
{
|
|
return VerifyAlterInvalidTableProperties(&m_pTable->GetTableID(), DBPROPSTATUS_BADOPTION,
|
|
DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL+1);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request, optional, an invalid value of TEMPTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_36()
|
|
{
|
|
return VerifyAlterInvalidTableProperties(&m_pTable->GetTableID(), DBPROPSTATUS_NOTSET,
|
|
DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE, (void *)1, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request, required, an invalid value of TEMPTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_37()
|
|
{
|
|
return VerifyAlterInvalidTableProperties(&m_pTable->GetTableID(), DBPROPSTATUS_BADVALUE,
|
|
DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE, (void *)(USHRT_MAX-1), DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(38)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Optional prop, colid was not DB_NULLID. Verify DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_38()
|
|
{
|
|
return VerifyAlterInvalidTableProperties(&m_pTable->GetTableID(), DBPROPSTATUS_NOTSET,
|
|
DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED, m_pTable->GetTableID());
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(39)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Required prop, colid was not DB_NULLID. Verify DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_39()
|
|
{
|
|
return VerifyAlterInvalidTableProperties(&m_pTable->GetTableID(), DBPROPSTATUS_BADCOLUMN,
|
|
DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED, m_pTable->GetTableID());
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(40)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use AlterTable to change table name. Verify using TABLES schema rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_40()
|
|
{
|
|
TBEGIN
|
|
BOOL fTableFound;
|
|
DBID TableID;
|
|
DBID NewTableID;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TableID = m_pTable->GetTableID();
|
|
|
|
// Verify that TABLES SCHEMA is supported
|
|
if( !GetTableSchemaInfo(m_pTable, TableID.uName.pwszName, &fTableFound) )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC(fTableFound == TRUE);
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
TESTC_(AlterTable(&(m_pTable->GetTableID()), &NewTableID), S_OK);
|
|
|
|
// Verify new table exists
|
|
TESTC(GetTableSchemaInfo(m_pTable, NewTableID.uName.pwszName ,&fTableFound));
|
|
TESTC(fTableFound == TRUE);
|
|
|
|
// Verify previous table no longer exists
|
|
TESTC(GetTableSchemaInfo(m_pTable, TableID.uName.pwszName ,&fTableFound));
|
|
TESTC(fTableFound == FALSE);
|
|
|
|
CLEANUP:
|
|
|
|
RestoreTableID(&NewTableID);
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(43)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Mult Threads changing table id. Verify that only one thread succeeds.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterTable::Variation_43()
|
|
{
|
|
TBEGIN
|
|
INIT_THREADS(MAX_THREADS);
|
|
|
|
ULONG cIter = 0;
|
|
BOOL fExists = FALSE;
|
|
BOOL fAlteredTableFound = FALSE;
|
|
HRESULT rghr[MAX_THREADS];
|
|
THREADARG rgTArg[MAX_THREADS];
|
|
|
|
memset(rghr, 0, sizeof(rghr));
|
|
|
|
//Setup Thread Arguments and Create Threads
|
|
for( cIter = 0; cIter < MAX_THREADS; cIter++ )
|
|
{
|
|
DBID NewTableID;
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
rgTArg[cIter].pFunc = (void *)this;
|
|
rgTArg[cIter].pArg1 = (void *)&rghr[cIter];
|
|
rgTArg[cIter].pArg2 = (void *)&m_pTable->GetTableIDRef();
|
|
rgTArg[cIter].pArg3 = (void *)&NewTableID;
|
|
|
|
CREATE_THREAD(cIter, Thread_AlterTable, &rgTArg[cIter]);
|
|
}
|
|
|
|
START_THREADS();
|
|
END_THREADS();
|
|
|
|
//
|
|
for( cIter = 0; cIter < MAX_THREADS; cIter++ )
|
|
{
|
|
DBID * pNewTableID = (DBID *)rgTArg[cIter].pArg3;
|
|
|
|
if( rghr[cIter] == S_OK )
|
|
{
|
|
if( fAlteredTableFound )
|
|
{
|
|
TERROR("Error. Two threads succeeded in altering the table.");
|
|
}
|
|
|
|
fAlteredTableFound = TRUE;
|
|
|
|
TESTC_(m_pTable->DoesTableExist(pNewTableID, &fExists), S_OK);
|
|
TESTC(fExists == TRUE);
|
|
|
|
RestoreTableID(pNewTableID);
|
|
}
|
|
else
|
|
{
|
|
// Some other thread must have changed the table name
|
|
CHECK(rghr[cIter], DB_E_NOTABLE);
|
|
|
|
TESTC_(m_pTable->DoesTableExist(pNewTableID, &fExists), S_OK);
|
|
TESTC(fExists == FALSE);
|
|
}
|
|
|
|
ReleaseDBID(pNewTableID, FALSE);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAlterTable::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCIAlterTable::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAlterColumn)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAlterColumn - Test Cases for AlterColumn method
|
|
//| Created: 8/6/99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAlterColumn::Init()
|
|
{
|
|
TBEGIN
|
|
IColumnsInfo * pIColumnsInfo = NULL;
|
|
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCIAlterTable::Init())
|
|
// }}
|
|
{
|
|
// Cache column metadata using CSchema object
|
|
m_pSchema = new CTable(g_pIOpenRowset);
|
|
|
|
// Now get the rowset which we'll use to populate the table
|
|
TESTC_(m_pTable->CreateRowset(USE_OPENROWSET, IID_IColumnsInfo, 0,
|
|
NULL, (IUnknown **)&pIColumnsInfo),S_OK);
|
|
TESTC_(m_pSchema->GetTableColumnInfo(&m_pTable->GetTableID(), pIColumnsInfo), S_OK);
|
|
TESTC_(m_pSchema->AddInfoFromColumnsSchemaRowset(g_pIOpenRowset, m_pTable->GetTableName()), S_OK);
|
|
|
|
TESTC_(m_pSchema->GetColInfo(1, m_Col), S_OK);
|
|
TESTC_(DuplicateDBID(*m_Col.GetColID(), &m_ColumnID), S_OK);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Connect with DBPROP_INIT_MODE read only access. Verify DB_SEC_E_PERMISSIONDENIED when altering a column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_1()
|
|
{
|
|
TBEGIN
|
|
IUnknown * pUnkReadSession = NULL;
|
|
IAlterTable * pIAlterTable = NULL;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_DBCID;
|
|
|
|
// Try to obtain a read only session
|
|
if( !GetReadOnlySession(&pUnkReadSession) )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC(VerifyInterface(pUnkReadSession, IID_IAlterTable, SESSION_INTERFACE,
|
|
(IUnknown**)&pIAlterTable));
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
TESTC_(pIAlterTable->AlterColumn(&(m_pTable->GetTableID()), m_Col.GetColID(), dwColumnDescFlags,
|
|
&ColumnDesc), DB_SEC_E_PERMISSIONDENIED);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
SAFE_RELEASE(pUnkReadSession);
|
|
SAFE_RELEASE(pIAlterTable);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Try to use AlterColumn to change a table name. Verify failure
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_2()
|
|
{
|
|
TBEGIN;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_DBCID;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
TESTC_(m_pIAlterTable->AlterColumn(&m_pTable->GetTableID(), &m_pTable->GetTableID(), dwColumnDescFlags,
|
|
&ColumnDesc), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call AlterColumn with multiple commands active which have open rowsets, though not on the table to be altered.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CRowset RowsetA;
|
|
CRowset RowsetB;
|
|
CRowset RowsetC;
|
|
IRowset * pIRowsetA = NULL;
|
|
IRowset * pIRowsetB = NULL;
|
|
IRowset * pIRowsetC = NULL;
|
|
DBID NewColumnID;
|
|
|
|
//Create a couple rowsets using ICommand::Execute
|
|
TESTC_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowsetA), S_OK);
|
|
TESTC_(RowsetB.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowsetB), S_OK);
|
|
TESTC_(RowsetC.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowsetC), S_OK);
|
|
|
|
TESTC_(MakeNewColumnID(&NewColumnID, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
TESTC(VerifyAlterColumnName(1, &NewColumnID));
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIRowsetA);
|
|
SAFE_RELEASE(pIRowsetB);
|
|
SAFE_RELEASE(pIRowsetC);
|
|
|
|
ReleaseDBID(&NewColumnID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use AlterColumn when a rowset is open on the table to be altered. Verify DB_E_TABLEINUSE, or if successful, verify DB_S_COLUMNSCHANGE on restart position
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_4()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CRowset RowsetA;
|
|
IRowset * pIRowset = NULL;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
//Create an updatable rowset using ICommand::Execute
|
|
RowsetA.SetTable(m_pTable, DELETETABLE_NO);
|
|
RowsetA.SetSettableProperty(DBPROP_IRowsetLocate, DBPROPSET_ROWSET);
|
|
RowsetA.SetSettableProperty(DBPROP_IRowsetChange, DBPROPSET_ROWSET);
|
|
|
|
TESTC_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowset), S_OK);
|
|
TESTC(DefaultObjectTesting(pIRowset, ROWSET_INTERFACE));
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
TEST2C_(hr = AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), S_OK, DB_E_TABLEINUSE);
|
|
|
|
if( S_OK == hr )
|
|
{
|
|
TESTC(CompareColumnMetaData(1, DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc));
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Use AlterColumn when a FO/RO rowset is open on the table to be altered. Verify DB_E_TABLEINUSE, or if successful, verify DB_S_COLUMNSCHANGE on restart position
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_5()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
CRowset RowsetA;
|
|
IRowset * pIRowset = NULL;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
//Create a rowset using ICommand::Execute
|
|
RowsetA.SetTable(m_pTable, DELETETABLE_NO);
|
|
TESTC_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, 0,
|
|
NULL, (IUnknown**)&pIRowset), S_OK);
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
TEST2C_(hr = AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), S_OK, DB_E_TABLEINUSE);
|
|
|
|
if( S_OK == hr )
|
|
{
|
|
TESTC(CompareColumnMetaData(1, DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc));
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is NULL. Verify E_INVALIDARG.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_6()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
TESTC_(AlterColumn(NULL, &m_ColumnID, DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnID is NULL. Verify E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_7()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), NULL,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc is NULL. Verify E_INVALIDARG.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_8()
|
|
{
|
|
TBEGIN
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &m_ColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID does not exist. Verify DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DBID NonExistentTableID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
TESTC_(MakeNewTableID(&NonExistentTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
|
|
TESTC_(AlterColumn(&NonExistentTableID, &m_ColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
ReleaseDBID(&NonExistentTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnID does not exist. Verify DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_10()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBID NonExistentColumnID;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
TESTC_(MakeNewColumnID(&NonExistentColumnID, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &NonExistentColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
ReleaseDBID(&NonExistentColumnID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is a null string. Verify DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_11()
|
|
{
|
|
TBEGIN
|
|
DBID NullTableID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&NullTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
SAFE_FREE(NullTableID.uName.pwszName);
|
|
|
|
TESTC_(AlterColumn(&NullTableID, &m_ColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&NullTableID, FALSE);
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID is an empty string. Verify DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_12()
|
|
{
|
|
TBEGIN
|
|
DBID EmptyTableID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewTableID(&EmptyTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
EmptyTableID.uName.pwszName[0] = L'\0';
|
|
|
|
TESTC_(AlterColumn(&EmptyTableID, &m_ColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_NOTABLE);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&EmptyTableID, FALSE);
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pTableID has invalid DBKIND. Verify DB_E_NOTABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_13()
|
|
{
|
|
TBEGIN
|
|
LONG eKind;
|
|
DBID TableID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
ColumnDesc.cPropertySets = 0;
|
|
ColumnDesc.rgPropertySets = NULL;
|
|
|
|
DuplicateDBID(m_pTable->GetTableID(), &TableID);
|
|
|
|
for( eKind = DBKIND_GUID_NAME; eKind <= DBKIND_GUID+1; eKind++ )
|
|
{
|
|
if( eKind == m_lDBIDType )
|
|
continue;
|
|
|
|
TableID.eKind = eKind;
|
|
TESTC_(AlterColumn(&TableID, &m_ColumnID,
|
|
DBCOLUMNDESCFLAGS_PROPERTIES, &ColumnDesc), DB_E_NOTABLE);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TableID.eKind = m_lDBIDType;
|
|
ReleaseDBID(&TableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnID is a null string. Verify DB_E_NOCOLUMN
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_14()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
ColumnDesc.cPropertySets = 0;
|
|
ColumnDesc.rgPropertySets = NULL;
|
|
|
|
TESTC_(DuplicateDBID(m_ColumnID, &ColumnID), S_OK);
|
|
SAFE_FREE(ColumnID.uName.pwszName);
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &ColumnID,
|
|
DBCOLUMNDESCFLAGS_PROPERTIES, &ColumnDesc), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnID is an empty string. Verify DB_E_NOCOLUMN.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_15()
|
|
{
|
|
TBEGIN
|
|
DBID ColumnID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
ColumnDesc.cPropertySets = 0;
|
|
ColumnDesc.rgPropertySets = NULL;
|
|
|
|
TESTC_(DuplicateDBID(m_ColumnID, &ColumnID), S_OK);
|
|
ColumnID.uName.pwszName[0] = L'\0';
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &ColumnID,
|
|
DBCOLUMNDESCFLAGS_PROPERTIES, &ColumnDesc), DB_E_NOCOLUMN);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnID has invalid DBKIND. Verify DB_E_NOCOLUMN.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_16()
|
|
{
|
|
TBEGIN
|
|
LONG eKind;
|
|
DBID ColumnID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
ColumnDesc.cPropertySets = 0;
|
|
ColumnDesc.rgPropertySets = NULL;
|
|
|
|
DuplicateDBID(m_ColumnID, &ColumnID);
|
|
|
|
for( eKind = DBKIND_GUID_NAME; eKind <= DBKIND_GUID+1; eKind++ )
|
|
{
|
|
if( eKind == m_lDBIDType )
|
|
continue;
|
|
|
|
if( (eKind == DBKIND_GUID_NAME ||
|
|
eKind == DBKIND_PGUID_NAME ||
|
|
eKind == DBKIND_NAME) &&
|
|
(m_lDBIDType == DBKIND_GUID_NAME ||
|
|
m_lDBIDType == DBKIND_PGUID_NAME ||
|
|
m_lDBIDType == DBKIND_NAME) )
|
|
continue;
|
|
|
|
ColumnID.eKind = eKind;
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &ColumnID,
|
|
DBCOLUMNDESCFLAGS_PROPERTIES, &ColumnDesc), DB_E_NOCOLUMN);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
ColumnID.eKind = m_lDBIDType;
|
|
ReleaseDBID(&ColumnID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ColumnDescFlags was not supported. Verify DB_E_NOTSUPPORTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_17()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwFlags = 0;
|
|
|
|
TESTC_(m_pTable->GetColInfo(1, col), S_OK);
|
|
TESTC_(m_pTable->BuildColumnDesc(&ColumnDesc, col), S_OK);
|
|
|
|
for( dwFlags = DBCOLUMNDESCFLAGS_TYPENAME; dwFlags <= DBCOLUMNDESCFLAGS_SCALE; dwFlags <<= 1)
|
|
{
|
|
if( (m_lAlterColumnSupport & dwFlags) == 0 )
|
|
{
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
dwFlags, &ColumnDesc), DB_E_NOTSUPPORTED);
|
|
}
|
|
}
|
|
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
~m_lAlterColumnSupport, &ColumnDesc), DB_E_NOTSUPPORTED);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseColumnDesc(&ColumnDesc, 1, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid ColumnDescFlags. Verify DB_E_NOTSUPPORTED.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_18()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(),
|
|
&m_ColumnID, DBCOLUMNDESCFLAGS_SCALE << 1, &ColumnDesc), DB_E_NOTSUPPORTED);
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(),
|
|
&m_ColumnID, LONG_MAX, &ColumnDesc), DB_E_NOTSUPPORTED);
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(),
|
|
&m_ColumnID, LONG_MIN, &ColumnDesc), DB_E_NOTSUPPORTED);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc contains an existing column id. Verify DB_E_DUPLICATECOLUMNID.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_19()
|
|
{
|
|
TBEGIN
|
|
DBID SourceColumnID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
ULONG i,j;
|
|
CCol sourceCol;
|
|
CCol DestCol;
|
|
|
|
memset(&ColumnDesc, 0, sizeof(DBID));
|
|
|
|
for( i=1; i <= m_pTable->CountColumnsOnSchema(); i++ )
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(i, sourceCol), S_OK);
|
|
TESTC_(DuplicateDBID(*sourceCol.GetColID(), &SourceColumnID), S_OK);
|
|
|
|
for( j=1; j <= m_pTable->CountColumnsOnSchema(); j++ )
|
|
{
|
|
if( i == j )
|
|
continue;
|
|
|
|
TESTC_(m_pTable->GetColInfo(j, DestCol), S_OK);
|
|
TESTC_(DuplicateDBID(*DestCol.GetColID(), &ColumnDesc.dbcid), S_OK);
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &SourceColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_DUPLICATECOLUMNID);
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
}
|
|
|
|
ReleaseDBID(&SourceColumnID, FALSE);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
ReleaseDBID(&SourceColumnID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc contains invalid DBKIND. Verify DB_E_BADCOLUMNID.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_20()
|
|
{
|
|
TBEGIN
|
|
LONG eKind;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
for( eKind = DBKIND_GUID_NAME; eKind <= DBKIND_GUID+1; eKind++ )
|
|
{
|
|
if( eKind == m_lDBIDType )
|
|
continue;
|
|
|
|
ColumnDesc.dbcid.eKind = eKind;
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &m_ColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_BADCOLUMNID);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
ColumnDesc.dbcid.eKind = m_lDBIDType;
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc contains empty string. Verify DB_E_BADCOLUMNID.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_21()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
ColumnDesc.dbcid.uName.pwszName[0] = L'\0';
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &m_ColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc contains NULL string. Verify DB_E_BADCOLUMNID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_22()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
SAFE_FREE(ColumnDesc.dbcid.uName.pwszName);
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &m_ColumnID,
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc contains an invalid precision, overflow and underflow. Verify DB_E_BADPRECISION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_23()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
ULONG cIter = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol col;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_PRECISION;
|
|
|
|
if( (m_lAlterColumnSupport & dwColumnDescFlags) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
if( col.GetProviderType() != DBTYPE_NUMERIC &&
|
|
col.GetProviderType() != DBTYPE_VARNUMERIC )
|
|
continue;
|
|
|
|
BYTE rgbPrecision[] =
|
|
{
|
|
0,
|
|
col.GetPrecision()+1,
|
|
};
|
|
|
|
for( cIter = 0; cIter < NUMELEM(rgbPrecision); cIter++ )
|
|
{
|
|
ColumnDesc.bPrecision = rgbPrecision[cIter];
|
|
|
|
hr = AlterColumn(&m_pTable->GetTableID(), col.GetColID(),
|
|
dwColumnDescFlags, &ColumnDesc);
|
|
CHECK(hr, DB_E_BADPRECISION);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc contains an invalid scale, both overflow and underflow. Verify DB_E_BADSCALE.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_24()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
ULONG cIter = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol col;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_SCALE;
|
|
|
|
if( (m_lAlterColumnSupport & dwColumnDescFlags) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
if( col.GetProviderType() != DBTYPE_NUMERIC &&
|
|
col.GetProviderType() != DBTYPE_VARNUMERIC &&
|
|
col.GetProviderType() != DBTYPE_DECIMAL )
|
|
continue;
|
|
|
|
BYTE rgbScale[] =
|
|
{
|
|
col.GetMinScale()-1,
|
|
col.GetPrecision()+1,
|
|
col.GetMaxScale()+1,
|
|
};
|
|
|
|
for( cIter = 0; cIter < NUMELEM(rgbScale); cIter++ )
|
|
{
|
|
ColumnDesc.bScale = rgbScale[cIter];
|
|
|
|
hr = AlterColumn(&m_pTable->GetTableID(), col.GetColID(),
|
|
dwColumnDescFlags, &ColumnDesc);
|
|
CHECK(hr, DB_E_BADSCALE);
|
|
}
|
|
|
|
// one last case with Scale > Precision
|
|
ColumnDesc.bPrecision = col.GetPrecision()/2;
|
|
ColumnDesc.bScale = ColumnDesc.bPrecision+1;
|
|
|
|
hr = AlterColumn(&m_pTable->GetTableID(), col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_PRECISION | DBCOLUMNDESCFLAGS_SCALE, &ColumnDesc);
|
|
CHECK(hr, DB_E_BADPRECISION);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc contains an invalid type name. Verify DB_E_BADTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_25()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_TYPENAME) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&ColumnDesc, 0xCC, sizeof(DBCOLUMNDESC));
|
|
|
|
ColumnDesc.pwszTypeName = NULL;
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_TYPENAME, &ColumnDesc), DB_E_BADTYPE);
|
|
|
|
ColumnDesc.pwszTypeName = L"";
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_TYPENAME, &ColumnDesc), DB_E_BADTYPE);
|
|
|
|
ColumnDesc.pwszTypeName = L"NonExistentTypeName";
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_TYPENAME, &ColumnDesc), DB_E_BADTYPE);
|
|
|
|
if( GetModInfo()->GetLocaleInfo() )
|
|
{
|
|
const ULONG cchTypeLen = 10;
|
|
WCHAR wszIntlString[cchTypeLen+1];
|
|
|
|
GetModInfo()->GetLocaleInfo()->MakeUnicodeIntlString(wszIntlString, cchTypeLen);
|
|
|
|
ColumnDesc.pwszTypeName = wszIntlString;
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_TYPENAME, &ColumnDesc), DB_E_BADTYPE);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc pColumnDesc contains an invalid DBTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_26()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_WTYPE) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&ColumnDesc, 0xFF, sizeof(DBCOLUMNDESC));
|
|
|
|
// max type
|
|
ColumnDesc.wType = DBTYPE_DBTIMESTAMP + 1;
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_WTYPE, &ColumnDesc), DB_E_BADTYPE);
|
|
|
|
// in valid range, but invalid
|
|
ColumnDesc.wType = DBTYPE_DECIMAL + 1;
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_WTYPE, &ColumnDesc), DB_E_BADTYPE);
|
|
|
|
// max possible value
|
|
ColumnDesc.wType = USHRT_MAX;
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_WTYPE, &ColumnDesc), DB_E_BADTYPE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc In pColumnDesc, cPropertySets > 0 and rgPropertySets is null. Verify E_INVALIDARG.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_27()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
ColumnDesc.cPropertySets = 1;
|
|
ColumnDesc.rgPropertySets = NULL;
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &m_ColumnID, DBCOLUMNDESCFLAGS_PROPERTIES,
|
|
&ColumnDesc), E_INVALIDARG);
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBCOLUMNDESCFLAG_DBCID. Change ID of columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_28()
|
|
{
|
|
TBEGIN
|
|
DBID NewColumnID;
|
|
size_t rgColumnLengths[] =
|
|
{
|
|
1, // one char table name
|
|
2, // two char table name
|
|
m_cchMaxColName/2, // medium length
|
|
m_cchMaxColName - 1, // max length - 1
|
|
m_cchMaxColName // max length
|
|
};
|
|
HRESULT hr;
|
|
ULONG ulOrdinal = 0;
|
|
ULONG cIter = 0;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_DBCID) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
if( m_cchMaxColName == ~0 )
|
|
{
|
|
// Unknown maximum length
|
|
size_t cchLen = wcslen(m_pTable->GetTableName());
|
|
|
|
rgColumnLengths[2] = cchLen/2;
|
|
rgColumnLengths[3] = cchLen-1;
|
|
rgColumnLengths[4] = cchLen;
|
|
}
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
|
|
odtLog << "Altering column ID for column " << ulOrdinal << ENDL;
|
|
|
|
// Try altering the column name to several interesting lengths.
|
|
for( cIter = 0; cIter < NUMELEM(rgColumnLengths); cIter++ )
|
|
{
|
|
if( rgColumnLengths[cIter] > m_cchMaxColName )
|
|
continue;
|
|
|
|
hr = MakeNewColumnID(&NewColumnID, DBKIND_NAME, rgColumnLengths[cIter]);
|
|
if( S_FALSE == hr )
|
|
continue;
|
|
|
|
TESTC_(hr, S_OK);
|
|
|
|
TESTC(VerifyAlterColumnName(ulOrdinal, &NewColumnID));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBCOLUMNDESCFLAGS_COLSIZE. Change column size of columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_29()
|
|
{
|
|
TBEGIN
|
|
ULONG cIter = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol col;
|
|
CCol onetablecol;
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags = DBCOLUMNDESCFLAGS_COLSIZE;
|
|
CTable * pTable = NULL;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_COLSIZE) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
// For each value in the schema rowset
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pFullSchemaInfo->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
DBCOLUMNDESC * pColumnDesc = NULL;
|
|
|
|
TESTC_(m_pFullSchemaInfo->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
// DBCOLUMNDESCFLAGS_COLSIZE applies only to STR/WSTR/BYTES
|
|
if( col.GetProviderType() != DBTYPE_STR &&
|
|
col.GetProviderType() != DBTYPE_WSTR &&
|
|
col.GetProviderType() != DBTYPE_BYTES )
|
|
continue;
|
|
|
|
if( col.GetCreateParams() == NULL)
|
|
continue;
|
|
|
|
pColumnDesc = (DBCOLUMNDESC *)PROVIDER_ALLOC(sizeof(DBCOLUMNDESC));
|
|
TESTC(pColumnDesc != NULL);
|
|
TESTC_(m_pTable->BuildColumnDesc(pColumnDesc, col), S_OK);
|
|
|
|
TESTC_(MakeNewColumnID(&pColumnDesc->dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
pColumnDesc->ulColumnSize = 1;
|
|
|
|
// Need to build a one column table to try this out.
|
|
// Important since Datasources often limit a row size
|
|
// to a page size.
|
|
// PrivLib table creation logic often tries to create
|
|
// row sizes near its limit.
|
|
// Trying to increase a column size on such a table
|
|
// will probably violate its row limit size.
|
|
// With a new one column table, we will be able to
|
|
// alter the size up to its column size limits
|
|
// as reported in the PROVIDER_TYPES schema rowset
|
|
pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(pTable != NULL);
|
|
|
|
pTable->SetBuildColumnDesc(FALSE);
|
|
pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
TESTC_(pTable->CreateTable(0,0,NULL,PRIMARY,TRUE), S_OK);
|
|
|
|
TESTC_(pTable->GetColInfo(1, onetablecol), S_OK);
|
|
DBLENGTH rgulColSize[] =
|
|
{
|
|
col.GetColumnSize(),
|
|
col.GetColumnSize()-1,
|
|
col.GetColumnSize()/2,
|
|
2,
|
|
1,
|
|
};
|
|
|
|
odtLog << "Altering column of type: " << onetablecol.GetProviderTypeName() << " to column size : ";
|
|
for( cIter = 0; cIter < NUMELEM(rgulColSize); cIter++ )
|
|
{
|
|
odtLog << ENDL << rgulColSize[cIter] << L".";
|
|
COMPARE(VerifyAlterColumnSize(1, rgulColSize[cIter], pTable), TRUE);
|
|
}
|
|
odtLog << ENDL;
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBCOLUMNDESCFLAGS_PRECISION. Change precision of columns.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_30()
|
|
{
|
|
TBEGIN
|
|
ULONG cIter = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol col;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_PRECISION) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
// DBCOLUMNDESCFLAGS_PRECISION only applies to NUMERIC and VARNUMERIC
|
|
if( col.GetProviderType() != DBTYPE_NUMERIC &&
|
|
col.GetProviderType() != DBTYPE_VARNUMERIC )
|
|
continue;
|
|
|
|
BYTE rgbPrecision[] =
|
|
{
|
|
1,
|
|
2,
|
|
col.GetScale(),
|
|
col.GetPrecision()/2,
|
|
col.GetPrecision() - 1,
|
|
col.GetPrecision()
|
|
};
|
|
|
|
for( cIter = 0; cIter < NUMELEM(rgbPrecision); cIter++ )
|
|
{
|
|
if( col.GetProviderType() == DBTYPE_NUMERIC && rgbPrecision[cIter] < col.GetScale() )
|
|
continue;
|
|
|
|
TESTC(VerifyAlterColumnPrecision(ulOrdinal, rgbPrecision[cIter]));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBCOLUMNDESCFLAGS_SCALE. Change scale of columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_31()
|
|
{
|
|
TBEGIN
|
|
ULONG cIter = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol col;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_SCALE) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
// DBCOLUMNDESCFLAGS_SCALE only applies to NUMERIC,VARNUMERIC, and DECIMAL
|
|
if( col.GetProviderType() != DBTYPE_NUMERIC &&
|
|
col.GetProviderType() != DBTYPE_VARNUMERIC &&
|
|
col.GetProviderType() != DBTYPE_DECIMAL )
|
|
continue;
|
|
|
|
BYTE rgbScale[] =
|
|
{
|
|
0,
|
|
1,
|
|
col.GetScale(),
|
|
col.GetPrecision()/2,
|
|
col.GetPrecision() - 1,
|
|
col.GetPrecision()
|
|
};
|
|
|
|
for( cIter = 0; cIter < NUMELEM(rgbScale); cIter++ )
|
|
{
|
|
if( rgbScale[cIter] < col.GetMinScale() ||
|
|
rgbScale[cIter] > col.GetMaxScale() )
|
|
continue;
|
|
|
|
TESTC(VerifyAlterColumnScale(ulOrdinal, rgbScale[cIter]));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBCOLUMNDESCFLAG_CLSID. Change clsid of columns.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_32()
|
|
{
|
|
TBEGIN
|
|
CLSID clsid;
|
|
ULONG ulOrdinal = 0;
|
|
|
|
memcpy(&clsid, &IID_IUnknown, sizeof(CLSID));
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_CLSID) == 0 )
|
|
{
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
ColumnDesc.pclsid = &clsid;
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(),
|
|
&m_ColumnID, DBCOLUMNDESCFLAGS_CLSID, &ColumnDesc), DB_E_NOTSUPPORTED);
|
|
}
|
|
else
|
|
{
|
|
// For each column in the table, try altering the CLSID of the column
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC(VerifyAlterColumnCLSID(ulOrdinal, &clsid));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBCOLUMNDESCFLAGS_WTYPE. Change dbtype of columns.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_33()
|
|
{
|
|
TBEGIN
|
|
ULONG cTypes = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol tablecol;
|
|
CCol typecol;
|
|
CTable * pTable = NULL;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_WTYPE) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(CreateTable(&pTable), S_OK);
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(pTable->GetColInfo(ulOrdinal, tablecol), S_OK);
|
|
if( tablecol.GetUnique() || tablecol.GetAutoInc() || tablecol.GetIsLong() || !tablecol.GetUpdateable() )
|
|
continue;
|
|
|
|
if( UpgradeType(&tablecol, &typecol) )
|
|
{
|
|
odtLog << "Altering column: " << ulOrdinal << " of type: " << tablecol.GetProviderTypeName() << " to type: " << typecol.GetProviderTypeName() << "." << ENDL;
|
|
TESTC_(SetChangeColInfo(&typecol), S_OK);
|
|
|
|
COMPARE(VerifyAlterColumnType(ulOrdinal, typecol.GetProviderType(), pTable), TRUE);
|
|
}
|
|
else
|
|
{
|
|
odtLog << "Couldn't find like type for column: " << ulOrdinal << " of type: " << tablecol.GetProviderTypeName() << ENDL;
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBCOLUMNDESC_TYPENAME. Change typename of columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_34()
|
|
{
|
|
BOOL fPass = FALSE;
|
|
ULONG cTypes = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol tablecol;
|
|
CCol typecol;
|
|
CTable * pTable = NULL;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_TYPENAME) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(CreateTable(&pTable), S_OK);
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(pTable->GetColInfo(ulOrdinal, tablecol), S_OK);
|
|
if( tablecol.GetUnique() || tablecol.GetAutoInc() || tablecol.GetIsLong() || !tablecol.GetUpdateable() )
|
|
continue;
|
|
|
|
if( UpgradeType(&tablecol, &typecol) )
|
|
{
|
|
odtLog << "Altering column: " << ulOrdinal << " of type: " << tablecol.GetProviderTypeName() << " to type: " << typecol.GetProviderTypeName() << "." << ENDL;
|
|
TESTC_(SetChangeColInfo(&typecol), S_OK);
|
|
|
|
fPass = VerifyAlterColumnTypeName(ulOrdinal, typecol.GetProviderTypeName(), pTable);
|
|
COMPARE(fPass, TRUE);
|
|
}
|
|
else
|
|
{
|
|
odtLog << "Couldn't find like type for column: " << ulOrdinal << " of type: " << tablecol.GetProviderTypeName() << ENDL;
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
return fPass;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBCOLUMNDESC_ITYPEINFO. Change type info of columns.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_35()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
ColumnDesc.pTypeInfo = INVALID(ITypeInfo *);
|
|
|
|
// DBCOLUMNDESCFLAGS_ITYPEINFO is reserved for future use and should not be supported.
|
|
TESTC( (DBCOLUMNDESCFLAGS_ITYPEINFO & m_lAlterColumnSupport) == 0 );
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(),
|
|
&m_ColumnID, DBCOLUMNDESCFLAGS_ITYPEINFO, &ColumnDesc), DB_E_NOTSUPPORTED);
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_FIXEDLENGTH
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_36()
|
|
{
|
|
TBEGIN
|
|
ULONG cTypes = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol tablecol;
|
|
CCol typecol;
|
|
BOOL fFixed;
|
|
CTable * pTable = NULL;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES | DBCOLUMNDESCFLAGS_WTYPE;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(CreateTable(&pTable), S_OK);
|
|
|
|
memset(&ColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= pTable->CountColumnsOnSchema(); ulOrdinal++ )
|
|
{
|
|
TESTC_(pTable->GetColInfo(ulOrdinal, tablecol), S_OK);
|
|
|
|
if( !tablecol.GetUpdateable() || tablecol.GetIsLong() )
|
|
continue;
|
|
|
|
if( tablecol.GetProviderType() == DBTYPE_WSTR ||
|
|
tablecol.GetProviderType() == DBTYPE_STR ||
|
|
tablecol.GetProviderType() == DBTYPE_BYTES )
|
|
{
|
|
if( UpgradeType(&tablecol, &typecol) )
|
|
{
|
|
odtLog << "Altering column: " << ulOrdinal << " of type: " << tablecol.GetProviderTypeName() << " to type: " << typecol.GetProviderTypeName() << "." << ENDL;
|
|
TESTC_(SetChangeColInfo(&typecol), S_OK);
|
|
|
|
// Get the FixedLength attribute of the new column
|
|
fFixed = typecol.GetIsFixedLength();
|
|
|
|
TESTC_(SetChangeColInfo(&typecol), S_OK);
|
|
|
|
ColumnDesc.wType = tablecol.GetProviderType();
|
|
|
|
::SetProperty(DBPROP_COL_FIXEDLENGTH, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(fFixed ? VARIANT_TRUE : VARIANT_FALSE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
COMPARE(VerifyAlterColumn(ulOrdinal, dwColumnDescFlags, &ColumnDesc, pTable), TRUE);
|
|
|
|
FreeProperties(&ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets);
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_ISLONG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_37()
|
|
{
|
|
TBEGIN
|
|
ULONG cTypes = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol tablecol;
|
|
CCol typecol;
|
|
BOOL fIsLong;
|
|
CTable * pTable = NULL;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES | DBCOLUMNDESCFLAGS_WTYPE;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(CreateTable(&pTable), S_OK);
|
|
|
|
memset(&ColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= pTable->CountColumnsOnSchema(); ulOrdinal++ )
|
|
{
|
|
TESTC_(pTable->GetColInfo(ulOrdinal, tablecol), S_OK);
|
|
|
|
if( !tablecol.GetUpdateable() )
|
|
continue;
|
|
|
|
if( tablecol.GetProviderType() == DBTYPE_WSTR ||
|
|
tablecol.GetProviderType() == DBTYPE_STR ||
|
|
tablecol.GetProviderType() == DBTYPE_BYTES )
|
|
{
|
|
if( UpgradeType(&tablecol, &typecol, TRUE) )
|
|
{
|
|
odtLog << "Altering column: " << ulOrdinal << " of type: " << tablecol.GetProviderTypeName() << " to type: " << typecol.GetProviderTypeName() << "." << ENDL;
|
|
TESTC_(SetChangeColInfo(&typecol), S_OK);
|
|
|
|
// Get the ISLONG attribute of the new column
|
|
fIsLong = typecol.GetIsLong();
|
|
|
|
TESTC_(SetChangeColInfo(&typecol), S_OK);
|
|
|
|
ColumnDesc.wType = tablecol.GetProviderType();
|
|
|
|
::SetProperty(DBPROP_COL_ISLONG, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(fIsLong ? VARIANT_TRUE : VARIANT_FALSE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
COMPARE(VerifyAlterColumn(ulOrdinal, dwColumnDescFlags, &ColumnDesc, pTable), TRUE);
|
|
|
|
FreeProperties(&ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets);
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(38)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_NULLABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_38()
|
|
{
|
|
TBEGIN
|
|
BOOL fNullable;
|
|
ULONG cTypes = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol tablecol;
|
|
CCol changecol;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_PROPERTIES) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, tablecol), S_OK);
|
|
|
|
if( tablecol.GetUnique() || tablecol.GetAutoInc() || !tablecol.GetUpdateable() )
|
|
continue;
|
|
|
|
// flip the NULLABLE attribute of the column
|
|
fNullable = !tablecol.GetNullable();
|
|
changecol = tablecol;
|
|
changecol.SetNullable(fNullable);
|
|
|
|
TESTC_(SetChangeColInfo(&changecol), S_OK);
|
|
|
|
TESTC(VerifyAlterColumnProperty(ulOrdinal, DBPROP_COL_NULLABLE, (void *)(fNullable ? VARIANT_TRUE : VARIANT_FALSE), DBTYPE_BOOL));
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(39)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_DESCRIPTION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_39()
|
|
{
|
|
TBEGIN
|
|
ULONG ulOrdinal = 0;
|
|
CCol tablecol;
|
|
CCol changecol;
|
|
WCHAR * pwszDescription = NULL;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_PROPERTIES) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
pwszDescription = MakeObjectName(L"IALTTAB", MAXBUFLEN);
|
|
TESTC(pwszDescription != NULL);
|
|
|
|
// For each column in the table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, tablecol), S_OK);
|
|
|
|
changecol = tablecol;
|
|
changecol.SetColDescription(pwszDescription);
|
|
|
|
odtLog << "Changing DESCRIPTION property on " << tablecol.GetColName() << ENDL;
|
|
|
|
if( CHECK(SetChangeColInfo(&changecol), S_OK) )
|
|
{
|
|
COMPARE(VerifyAlterColumnProperty(ulOrdinal, DBPROP_COL_DESCRIPTION, (void *)pwszDescription, DBTYPE_BSTR), TRUE);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_FREE(pwszDescription);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(40)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_UNIQUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_40()
|
|
{
|
|
return AlterPropertyAndVerifyRowset(DBPROP_COL_UNIQUE);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(41)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COLUMNLCID
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_41()
|
|
{
|
|
TBEGIN
|
|
ULONG cIter = 0;
|
|
ULONG ulOrdinal = 0;
|
|
CCol col;
|
|
CCol onetablecol;
|
|
CCol changecol;
|
|
CTable * pTable = NULL;
|
|
LONG lLCID = 0;
|
|
IColumnsInfo * pIColumnsInfo = NULL;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_PROPERTIES) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
// For each value in the schema rowset
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pFullSchemaInfo->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
DBCOLUMNDESC * pColumnDesc = NULL;
|
|
|
|
TESTC_(m_pFullSchemaInfo->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
// DBPROP_COL_COLUMNLCID applies only to STR/WSTR/BYTES
|
|
if( col.GetProviderType() != DBTYPE_STR &&
|
|
col.GetProviderType() != DBTYPE_WSTR &&
|
|
col.GetProviderType() != DBTYPE_BYTES )
|
|
continue;
|
|
|
|
if( col.GetCreateParams() == NULL)
|
|
continue;
|
|
|
|
pColumnDesc = (DBCOLUMNDESC *)PROVIDER_ALLOC(sizeof(DBCOLUMNDESC));
|
|
TESTC(pColumnDesc != NULL);
|
|
TESTC_(m_pTable->BuildColumnDesc(pColumnDesc, col), S_OK);
|
|
|
|
TESTC_(MakeNewColumnID(&pColumnDesc->dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
// Create fresh table
|
|
pTable = new CTable(g_pIOpenRowset, L"IALTTAB");
|
|
TESTC(pTable != NULL);
|
|
|
|
pTable->SetBuildColumnDesc(FALSE);
|
|
pTable->SetColumnDesc(pColumnDesc, 1);
|
|
|
|
TESTC_(pTable->CreateTable(0,0,NULL,PRIMARY,TRUE), S_OK);
|
|
|
|
TESTC_(pTable->CreateRowset(USE_OPENROWSET, IID_IColumnsInfo, 0,
|
|
NULL, (IUnknown **)&pIColumnsInfo),S_OK);
|
|
|
|
TESTC_(pTable->GetTableColumnInfo(&pTable->GetTableID(), pIColumnsInfo), S_OK);
|
|
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
|
|
|
|
TESTC_(pTable->GetColInfo(1, onetablecol), S_OK);
|
|
|
|
if( onetablecol.GetLCID() == 0 )
|
|
{
|
|
// unable to determine column LCID
|
|
TWARNING("Will not be able to verify column LCID.");
|
|
}
|
|
else
|
|
{
|
|
if( GetUserDefaultLCID() == LOCALE_ENGLISH_US )
|
|
{
|
|
if( onetablecol.GetLCID() == LOCALE_ENGLISH_US )
|
|
{
|
|
// Try German LCID since that is at least the same code page
|
|
lLCID = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), SORT_DEFAULT);
|
|
}
|
|
else
|
|
{
|
|
lLCID = LOCALE_ENGLISH_US;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( onetablecol.GetLCID() == GetUserDefaultLCID() )
|
|
lLCID = LOCALE_ENGLISH_US;
|
|
else
|
|
lLCID = GetUserDefaultLCID();
|
|
}
|
|
}
|
|
|
|
changecol = onetablecol;
|
|
changecol.SetLCID(lLCID);
|
|
|
|
TESTC_(SetChangeColInfo(&changecol), S_OK);
|
|
|
|
COMPARE(VerifyAlterColumnProperty(ulOrdinal, DBPROP_COLUMNLCID, (void *)(LONG_PTR)lLCID, DBTYPE_I4), TRUE);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_FREE(pIColumnsInfo);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(42)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_PRIMARYKEY
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_42()
|
|
{
|
|
return AlterPropertyAndVerifyRowset(DBPROP_COL_PRIMARYKEY);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(43)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_DEFAULT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_43()
|
|
{
|
|
return AlterPropertyAndVerifyRowset(DBPROP_COL_DEFAULT);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(44)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_COL_AUTOINCREMENT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_44()
|
|
{
|
|
return AlterPropertyAndVerifyRowset(DBPROP_COL_AUTOINCREMENT);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(45)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multiple attribute change
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_45()
|
|
{
|
|
// TO DO: Add your own code here
|
|
return TRUE;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(46)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Test atomicity. Valid new ID but one other invalid attribute
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_46()
|
|
{
|
|
ULONG ulOrdinal;
|
|
DBCOLUMNDESC * pColumnDesc = NULL;
|
|
DBCOLUMNDESC AlterColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_DBCID | DBCOLUMNDESCFLAGS_TYPENAME;
|
|
CCol col;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&AlterColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
// Make new column name and set invalid type name
|
|
TESTC_(MakeNewColumnID(&AlterColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
AlterColumnDesc.pwszTypeName = L"GARBAGE";
|
|
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
if( col.GetIsLong() || !col.GetUpdateable() )
|
|
continue;
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), col.GetColID(),
|
|
dwColumnDescFlags, &AlterColumnDesc), DB_E_BADTYPE);
|
|
|
|
// Verify that column hasn't changed
|
|
TESTC(CompareColumnMetaData(ulOrdinal, 0, NULL));
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&AlterColumnDesc.dbcid, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(47)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Test atomicity. Drop UNIQUE constraint and change to invalid type
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_47()
|
|
{
|
|
ULONG ulOrdinal;
|
|
DBCOLUMNDESC * pColumnDesc = NULL;
|
|
DBCOLUMNDESC AlterColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES|DBCOLUMNDESCFLAGS_WTYPE;
|
|
CCol col;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&AlterColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
// Look for a UNIQUE column
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
if( !col.GetUnique() )
|
|
continue;
|
|
|
|
::SetProperty(DBPROP_COL_UNIQUE, DBPROPSET_COLUMN, &AlterColumnDesc.cPropertySets,
|
|
&AlterColumnDesc.rgPropertySets, (void *)VARIANT_FALSE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
// Set invalid TYPE
|
|
AlterColumnDesc.wType = DBTYPE_DBTIMESTAMP + 1;
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), col.GetColID(),
|
|
dwColumnDescFlags, &AlterColumnDesc), DB_E_BADTYPE);
|
|
|
|
// Verify that column hasn't changed
|
|
TESTC(CompareColumnMetaData(ulOrdinal, 0, NULL));
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(48)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc In an element of rgPropertySets, cProperties was > 0 but rgProperties was not null
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_48()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBPROPSET PropSet;
|
|
|
|
ColumnDesc.cPropertySets = 1;
|
|
ColumnDesc.rgPropertySets = &PropSet;
|
|
|
|
PropSet.guidPropertySet = DBPROPSET_COLUMN;
|
|
PropSet.cProperties = 1;
|
|
PropSet.rgProperties = NULL;
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), &m_ColumnID, DBCOLUMNDESCFLAGS_PROPERTIES,
|
|
&ColumnDesc), E_INVALIDARG);
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(49)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Drop multiple constraints
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_49()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
ULONG ulOrdinal = 0;
|
|
CCol col;
|
|
CCol onetablecol;
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES;
|
|
CTable * pTable = NULL;
|
|
void * pDefaultData = NULL;
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET * rgPropSets = NULL;
|
|
DBCOLUMNDESC AlterColumnDesc;
|
|
DBTYPE wDefaultType;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_PROPERTIES) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&AlterColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
// Create a normal table.
|
|
// Add a PRIMARY KEY and a DEFAULT value
|
|
|
|
// For each column in our Table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
CCol onetablecol;
|
|
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
if( col.GetIsLong() || col.GetAutoInc() || col.GetProviderType() == DBTYPE_BOOL || !col.GetUpdateable())
|
|
continue;
|
|
|
|
odtLog << "Dropping constraints on column: " << ulOrdinal << " of type: " << col.GetColName() << ENDL ;
|
|
|
|
// Add a unique constraint
|
|
::SetProperty(DBPROP_COL_UNIQUE, DBPROPSET_COLUMN, &cPropSets,
|
|
&rgPropSets, (void *)VARIANT_TRUE, VT_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC(MakeDefaultData(&col, &pDefaultData, &wDefaultType, m_pTable));
|
|
|
|
// Add a default value
|
|
::SetProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN, &cPropSets,
|
|
&rgPropSets, pDefaultData, wDefaultType, DBPROPOPTIONS_REQUIRED);
|
|
|
|
CHECK(hr = CreateOneColTableWithProps(&pTable, &col, cPropSets, rgPropSets), S_OK);
|
|
if( S_OK == hr )
|
|
{
|
|
TESTC_(pTable->GetColInfo(1, onetablecol), S_OK);
|
|
|
|
// The new table should have a default value
|
|
// Cannot proceed if the Columnmetadata does not have default value info
|
|
TESTC(VerifyTableDefault(pTable, TRUE));
|
|
|
|
// Now remove the UNIQUE constraint
|
|
::SetProperty(DBPROP_COL_UNIQUE, DBPROPSET_COLUMN, &AlterColumnDesc.cPropertySets,
|
|
&AlterColumnDesc.rgPropertySets, (void *)VARIANT_FALSE, VT_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
// Remove default value
|
|
::SetProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN, &AlterColumnDesc.cPropertySets,
|
|
&AlterColumnDesc.rgPropertySets, (void *)NULL, VT_EMPTY, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(hr = AlterColumn(&pTable->GetTableID(), onetablecol.GetColID(),
|
|
ColumnDescFlags, &AlterColumnDesc), S_OK);
|
|
|
|
// Verification of DEFAULT
|
|
COMPARE(VerifyTableDefault(pTable, FALSE), TRUE);
|
|
|
|
// Verification of UNIQUE
|
|
COMPARE(VerifyTableUnique(pTable, FALSE), TRUE);
|
|
}
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
ReleaseDefaultData(pDefaultData, wDefaultType);
|
|
|
|
::FreeProperties(&cPropSets, &rgPropSets);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
::FreeProperties(&cPropSets, &rgPropSets);
|
|
::FreeProperties(&AlterColumnDesc.cPropertySets, &AlterColumnDesc.rgPropertySets);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(50)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Add multiple constraints
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_50()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
ULONG ulOrdinal = 0;
|
|
CCol col;
|
|
CCol onetablecol;
|
|
DBCOLUMNDESCFLAGS ColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES;
|
|
CTable * pTable = NULL;
|
|
void * pDefaultData = NULL;
|
|
DBCOLUMNDESC AlterColumnDesc;
|
|
DBTYPE wDefaultType;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_PROPERTIES) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&AlterColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
// Create a normal table.
|
|
// Add a PRIMARY KEY and a DEFAULT value
|
|
|
|
// For each column in our Table
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
CCol onetablecol;
|
|
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
if( col.GetIsLong() || col.GetAutoInc() || col.GetProviderType() == DBTYPE_BOOL || !col.GetUpdateable())
|
|
continue;
|
|
|
|
odtLog << "Adding constraints on column: " << ulOrdinal << " of type: " << col.GetColName() << ENDL ;
|
|
|
|
TESTC_(CreateOneColTableWithProps(&pTable, &col, 0, 0), S_OK);
|
|
TESTC_(pTable->GetColInfo(1, onetablecol), S_OK);
|
|
|
|
// The new table should not have a default value
|
|
// Cannot proceed if the Columnmetadata does not have default value info
|
|
TESTC(VerifyTableDefault(pTable, FALSE));
|
|
|
|
// Add a primary key
|
|
::SetProperty(DBPROP_COL_PRIMARYKEY, DBPROPSET_COLUMN, &AlterColumnDesc.cPropertySets,
|
|
&AlterColumnDesc.rgPropertySets, (void *)VARIANT_FALSE, VT_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC(MakeDefaultData(&col, &pDefaultData, &wDefaultType, m_pTable));
|
|
|
|
// Add a default value
|
|
::SetProperty(DBPROP_COL_DEFAULT, DBPROPSET_COLUMN, &AlterColumnDesc.cPropertySets,
|
|
&AlterColumnDesc.rgPropertySets, pDefaultData, wDefaultType, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(hr = AlterColumn(&pTable->GetTableID(), onetablecol.GetColID(),
|
|
ColumnDescFlags, &AlterColumnDesc), S_OK);
|
|
|
|
// Verification of DEFAULT
|
|
COMPARE(VerifyTableDefault(pTable, TRUE), TRUE);
|
|
|
|
// Verification of UNIQUE
|
|
COMPARE(VerifyTableUnique(pTable, TRUE), TRUE);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
ReleaseDefaultData(pDefaultData, wDefaultType);
|
|
|
|
::FreeProperties(&AlterColumnDesc.cPropertySets, &AlterColumnDesc.rgPropertySets);
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
::FreeProperties(&AlterColumnDesc.cPropertySets, &AlterColumnDesc.rgPropertySets);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(51)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Test atomicity. Alter column id along with unsupported ColumnDescFlag
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_51()
|
|
{
|
|
TBEGIN
|
|
CCol col;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColFlag = 0;
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_DBCID) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(m_pTable->GetColInfo(1, col), S_OK);
|
|
TESTC_(m_pTable->BuildColumnDesc(&ColumnDesc, col), S_OK);
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
for( dwColFlag = DBCOLUMNDESCFLAGS_TYPENAME; dwColFlag <= DBCOLUMNDESCFLAGS_SCALE; dwColFlag <<= 1)
|
|
{
|
|
if( (m_lAlterColumnSupport & dwColFlag) == 0 )
|
|
{
|
|
if(CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
dwColFlag | DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_NOTSUPPORTED))
|
|
{
|
|
// Verify no changes
|
|
COMPARE(CompareColumnMetaData(1, 0, NULL), TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
CHECK(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
(~m_lAlterColumnSupport) | DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_NOTSUPPORTED);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseColumnDesc(&ColumnDesc, 1, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(52)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request BLOB using DBPROP_COL_ISLONG,FIXEDLENGTH
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_52()
|
|
{
|
|
AlterStringCol2BLOB(DBTYPE_STR, TRUE);
|
|
AlterStringCol2BLOB(DBTYPE_STR, FALSE);
|
|
AlterStringCol2BLOB(DBTYPE_WSTR, TRUE);
|
|
AlterStringCol2BLOB(DBTYPE_WSTR, FALSE);
|
|
AlterStringCol2BLOB(DBTYPE_BYTES, TRUE);
|
|
AlterStringCol2BLOB(DBTYPE_BYTES, FALSE);
|
|
|
|
return TEST_PASS;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(53)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request DBPROP_COL_NULLABLE on non-nullable type. Verify error
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_53()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
ULONG ulOrdinal;
|
|
ULONG ulNonNullableCol = 0;
|
|
CCol schemacol;
|
|
CCol col;
|
|
CTable * pTable = NULL;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&ColumnDesc, 0, sizeof(ColumnDesc));
|
|
|
|
// Find a non-nullable column
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pFullSchemaInfo->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pFullSchemaInfo->GetColInfo(ulOrdinal, schemacol), S_OK);
|
|
|
|
if( schemacol.GetNullable() == FALSE )
|
|
{
|
|
ulNonNullableCol = ulOrdinal;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ulNonNullableCol == 0 )
|
|
{
|
|
odtLog << "Nonnullable column was not found" << ENDL;
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Create a table based on schemacol
|
|
TESTC_(CreateOneColTableWithProps(&pTable, &schemacol, 0, NULL), S_OK);
|
|
|
|
// Set Nullable FALSE
|
|
::SetProperty(DBPROP_COL_NULLABLE, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(VARIANT_TRUE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(pTable->GetColInfo(1, col), S_OK);
|
|
|
|
hr = AlterColumn(&pTable->GetTableID(), col.GetColID(),
|
|
dwColumnDescFlags, &ColumnDesc);
|
|
|
|
TESTC_(hr, DB_E_ERRORSOCCURRED);
|
|
TESTC(ColumnDesc.rgPropertySets[0].rgProperties[0].dwStatus == DBPROPSTATUS_BADVALUE ||
|
|
ColumnDesc.rgPropertySets[0].rgProperties[0].dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
|
|
CLEANUP:
|
|
|
|
FreeProperties(&ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(54)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request PRIMARYKEY and UNIQUE constraints - verify error
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_54()
|
|
{
|
|
TBEGIN
|
|
ULONG ulOrdinal;
|
|
CCol schemacol;
|
|
CTable * pTable = NULL;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES;
|
|
CCol TempCol;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&ColumnDesc, 0, sizeof(ColumnDesc));
|
|
|
|
// Find a non-nullable column
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pSchema->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pSchema->GetColInfo(ulOrdinal, schemacol), S_OK);
|
|
|
|
if( !schemacol.GetUnique() && !schemacol.GetAutoInc() &&! schemacol.GetIsLong() &&
|
|
schemacol.GetUpdateable() )
|
|
break;
|
|
}
|
|
|
|
if( ulOrdinal == m_pSchema->CountColumnsOnSchema() )
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Create a table based on schemacol
|
|
TESTC_(CreateOneColTableWithProps(&pTable, &schemacol, 0, NULL), S_OK);
|
|
|
|
// Set Unique and Primary key to TRUE
|
|
::SetProperty(DBPROP_COL_UNIQUE, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(VARIANT_TRUE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
::SetProperty(DBPROP_COL_PRIMARYKEY, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(VARIANT_TRUE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(pTable->GetColInfo(1, TempCol), S_OK);
|
|
|
|
TESTC_(AlterColumn(&pTable->GetTableID(), TempCol.GetColID(),
|
|
dwColumnDescFlags, &ColumnDesc), DB_E_ERRORSOCCURRED);
|
|
|
|
//DBPROP_COL_UNIQUE
|
|
TESTC(VerifyPropStatus(ColumnDesc.cPropertySets, ColumnDesc.rgPropertySets, DBPROP_COL_UNIQUE, DBPROPSET_COLUMN, DBPROPSTATUS_OK));
|
|
|
|
//DBPROP_COL_PRIMARYKEY
|
|
TESTC(VerifyPropStatus(ColumnDesc.cPropertySets, ColumnDesc.rgPropertySets, DBPROP_COL_PRIMARYKEY, DBPROPSET_COLUMN, DBPROPSTATUS_CONFLICTING));
|
|
|
|
CLEANUP:
|
|
|
|
FreeProperties(&ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(55)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request AutoInc on non AUTO_UNIQUE_VALUE. Verify error
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_55()
|
|
{
|
|
TBEGIN
|
|
ULONG ulOrdinal;
|
|
ULONG ulNonAutoIncCol = 0;
|
|
CCol schemacol;
|
|
CCol schemacolBLOB;
|
|
CTable * pTable = NULL;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&ColumnDesc, 0, sizeof(ColumnDesc));
|
|
|
|
// Find a non-nullable column
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pSchema->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pSchema->GetColInfo(ulOrdinal, schemacol), S_OK);
|
|
|
|
if( schemacol.CanAutoInc() == FALSE )
|
|
{
|
|
ulNonAutoIncCol = ulOrdinal;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ulNonAutoIncCol == 0 )
|
|
{
|
|
odtLog << "Non auto inc column was not found" << ENDL;
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Create a table based on schemacol
|
|
TESTC_(CreateOneColTableWithProps(&pTable, &schemacol, 0, NULL), S_OK);
|
|
|
|
// Set AUTOINC True
|
|
::SetProperty(DBPROP_COL_AUTOINCREMENT, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(VARIANT_TRUE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
COMPARE(VerifyAlterColumn(1, dwColumnDescFlags, &ColumnDesc, pTable), TRUE);
|
|
|
|
CLEANUP:
|
|
|
|
FreeProperties(&ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(56)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Request ISLONG with FIXEDLENGTH true. Verify Error
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_56()
|
|
{
|
|
TBEGIN
|
|
ULONG ulOrdinal;
|
|
CCol schemacol;
|
|
CTable * pTable = NULL;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_PROPERTIES;
|
|
CCol TempCol;
|
|
DBPROP * pProp = NULL;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&ColumnDesc, 0, sizeof(ColumnDesc));
|
|
|
|
// Find a non-nullable column
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pSchema->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pSchema->GetColInfo(ulOrdinal, schemacol), S_OK);
|
|
|
|
if( !schemacol.GetUnique() && !schemacol.GetAutoInc() && !schemacol.GetIsLong() &&
|
|
schemacol.GetUpdateable() && schemacol.GetProviderType() == DBTYPE_STR )
|
|
break;
|
|
}
|
|
|
|
if( ulOrdinal == m_pSchema->CountColumnsOnSchema() )
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
// Create a table based on schemacol
|
|
TESTC_(CreateOneColTableWithProps(&pTable, &schemacol, 0, NULL), S_OK);
|
|
|
|
// Set ISLONG and FIXED properties to TRUE
|
|
::SetProperty(DBPROP_COL_ISLONG, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(VARIANT_TRUE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
::SetProperty(DBPROP_COL_FIXEDLENGTH, DBPROPSET_COLUMN, &ColumnDesc.cPropertySets,
|
|
&ColumnDesc.rgPropertySets, (void *)(VARIANT_TRUE),
|
|
DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
|
|
TESTC_(pTable->GetColInfo(1, TempCol), S_OK);
|
|
|
|
TESTC_(AlterColumn(&pTable->GetTableID(), TempCol.GetColID(),
|
|
dwColumnDescFlags, &ColumnDesc), DB_E_ERRORSOCCURRED);
|
|
|
|
//DBPROP_COL_ISLONG
|
|
TESTC(VerifyPropStatus(ColumnDesc.cPropertySets, ColumnDesc.rgPropertySets, DBPROP_COL_ISLONG, DBPROPSET_COLUMN, DBPROPSTATUS_OK));
|
|
|
|
TESTC(FindProperty(DBPROP_COL_ISLONG, DBPROPSET_COLUMN, ColumnDesc.cPropertySets, ColumnDesc.rgPropertySets, &pProp))
|
|
|
|
|
|
if( pProp->dwStatus == DBPROPSTATUS_NOTSUPPORTED )
|
|
{
|
|
TESTC(VerifyPropStatus(ColumnDesc.cPropertySets, ColumnDesc.rgPropertySets, DBPROP_COL_FIXEDLENGTH, DBPROPSET_COLUMN, DBPROPSTATUS_OK));
|
|
}
|
|
else
|
|
{
|
|
TESTC(VerifyPropStatus(ColumnDesc.cPropertySets, ColumnDesc.rgPropertySets, DBPROP_COL_FIXEDLENGTH, DBPROPSET_COLUMN, DBPROPSTATUS_CONFLICTING));
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
FreeProperties(&ColumnDesc.cPropertySets, &ColumnDesc.rgPropertySets);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(57)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Threads. Test one thread altering a distinct col. Verify each thread succeeds.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_57()
|
|
{
|
|
TBEGIN
|
|
INIT_THREADS(MAX_THREADS);
|
|
|
|
ULONG cIter = 0;
|
|
DBORDINAL ulColOrdinal = 0;
|
|
DBID rgColumnID[MAX_THREADS];
|
|
THREADARG rgTArg[MAX_THREADS];
|
|
|
|
if( (m_lAlterColumnSupport & DBCOLUMNDESCFLAGS_DBCID) == 0 )
|
|
return TEST_SKIPPED;
|
|
|
|
//Setup Thread Arguments and Create Threads
|
|
for( cIter = 0; cIter < MAX_THREADS; cIter++ )
|
|
{
|
|
ulColOrdinal = cIter + 1;
|
|
// Create a thread to alter each column up to MAX_THREADS.
|
|
if( ulColOrdinal > m_pSchema->CountColumnsOnSchema() )
|
|
break;
|
|
|
|
TESTC_(MakeNewColumnID(&rgColumnID[cIter], m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
rgTArg[cIter].pFunc = (void *)this;
|
|
rgTArg[cIter].pArg1 = (void *)ulColOrdinal;
|
|
rgTArg[cIter].pArg2 = (void *)&rgColumnID[cIter];
|
|
|
|
CREATE_THREAD(cIter, Thread_AlterColumn, &rgTArg[cIter]);
|
|
}
|
|
|
|
START_THREADS();
|
|
END_THREADS();
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(58)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ColumnDescFlags is 0. Verify no-op
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_58()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
DBCOLUMNDESC ColumnDescCheck;
|
|
|
|
memset(&ColumnDesc, 0xFF, sizeof(DBCOLUMNDESC));
|
|
memset(&ColumnDescCheck, 0xFF, sizeof(DBCOLUMNDESC));
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(),
|
|
&m_ColumnID, 0, &ColumnDesc), S_OK);
|
|
|
|
TESTC(0 == memcmp(&ColumnDesc, &ColumnDescCheck, sizeof(DBCOLUMNDESC)));
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(59)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Change Column ID and use new Column ID in select stmt
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_59()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
CTable * pTable = NULL;
|
|
CRowset Rowset;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
if( m_pTable->GetSQLSupport() == DBPROPVAL_SQL_NONE )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(CreateTable(&pTable), S_OK);
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
{
|
|
CCol &NewCol = pTable->GetColInfoForUpdate(1);
|
|
|
|
TESTC_(AlterColumn(&pTable->GetTableID(), NewCol.GetColID(),
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), S_OK);
|
|
|
|
NewCol.SetColName( ColumnDesc.dbcid.uName.pwszName );
|
|
NewCol.SetColID( &ColumnDesc.dbcid );
|
|
|
|
TESTC_(Rowset.CreateRowset(SELECT_COLLISTFROMTBL, IID_IRowset, pTable), S_OK);
|
|
TESTC(Rowset.VerifyAllRows());
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(60)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Change column id to invalid keyword. Verify Error
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_60()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
if( m_lDBIDType != DBKIND_NAME )
|
|
return TEST_SKIPPED;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
SAFE_FREE(ColumnDesc.dbcid.uName.pwszName);
|
|
|
|
ColumnDesc.dbcid.uName.pwszName = L"select";
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), m_Col.GetColID(),
|
|
DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), DB_E_BADCOLUMNID);
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(61)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Combination E_INVALIDARG conditiions
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_61()
|
|
{
|
|
TBEGIN
|
|
DBCOLUMNDESC ColumnDesc;
|
|
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), NULL, DBCOLUMNDESCFLAGS_DBCID, NULL), E_INVALIDARG);
|
|
TESTC_(AlterColumn(NULL, m_Col.GetColID(), DBCOLUMNDESCFLAGS_DBCID, NULL), E_INVALIDARG);
|
|
TESTC_(AlterColumn(NULL, NULL, DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), E_INVALIDARG);
|
|
TESTC_(AlterColumn(NULL, NULL, DBCOLUMNDESCFLAGS_DBCID, NULL), E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(62)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc WTYPE and TYPENAME mismatch. Verify DB_E_BADTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_62()
|
|
{
|
|
ULONG ulOrdinal;
|
|
DBCOLUMNDESC AlterColumnDesc;
|
|
DBCOLUMNDESCFLAGS dwColumnDescFlags = DBCOLUMNDESCFLAGS_WTYPE | DBCOLUMNDESCFLAGS_TYPENAME;
|
|
CCol col;
|
|
|
|
if( ~m_lAlterColumnSupport & dwColumnDescFlags )
|
|
return TEST_SKIPPED;
|
|
|
|
memset(&AlterColumnDesc, 0, sizeof(DBCOLUMNDESC));
|
|
|
|
|
|
// Find an numeric type
|
|
for( ulOrdinal = 1; ulOrdinal <= m_pTable->CountColumnsOnSchema(); ulOrdinal++)
|
|
{
|
|
TESTC_(m_pTable->GetColInfo(ulOrdinal, col), S_OK);
|
|
|
|
if( col.GetUpdateable() && DBTYPE_I4 == col.GetProviderType() )
|
|
break;
|
|
}
|
|
|
|
if( ulOrdinal > m_pTable->CountColumnsOnSchema() )
|
|
return TEST_SKIPPED;
|
|
|
|
AlterColumnDesc.pwszTypeName = col.GetProviderTypeName();
|
|
AlterColumnDesc.wType = DBTYPE_NUMERIC;
|
|
|
|
TESTC_(AlterColumn(&m_pTable->GetTableID(), col.GetColID(),
|
|
dwColumnDescFlags, &AlterColumnDesc), DB_E_BADTYPE);
|
|
|
|
// Verify that column hasn't changed
|
|
TESTC(CompareColumnMetaData(ulOrdinal, 0, NULL));
|
|
|
|
CLEANUP:
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(63)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SupportedTXNDDL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_63()
|
|
{
|
|
TBEGIN
|
|
|
|
CTable * pTable = NULL;
|
|
IAlterTable * pIAlterTable = NULL;
|
|
ITransactionLocal * pITransactionLocal = NULL;
|
|
CCol col;
|
|
BOOL fExists;
|
|
DBID NewTableID;
|
|
DBCOLUMNDESC ColumnDesc;
|
|
VARIANT vSupportedTxnDDL;
|
|
|
|
TESTC_PROVIDER(VerifyInterface(m_pIAlterTable, IID_ITransactionLocal,
|
|
SESSION_INTERFACE, (IUnknown**)&pITransactionLocal));
|
|
|
|
VariantInit(&vSupportedTxnDDL);
|
|
TESTC_PROVIDER(GetProperty(DBPROP_SUPPORTEDTXNDDL, DBPROPSET_DATASOURCEINFO,
|
|
g_pIDBInitialize, &vSupportedTxnDDL));
|
|
|
|
TESTC(VT_I4 == vSupportedTxnDDL.vt);
|
|
TESTC_PROVIDER(DBPROPVAL_TC_NONE != vSupportedTxnDDL.lVal);
|
|
|
|
// Create a separate session
|
|
TESTC_(CreateNewSession(g_pIDBInitialize, IID_IAlterTable, (IUnknown **)&pIAlterTable), S_OK);
|
|
|
|
// create a table and populate it
|
|
TESTC_(CreateTable(&pTable), S_OK);
|
|
TESTC_(pTable->GetColInfo(1, col), S_OK);
|
|
|
|
TESTC_(MakeNewTableID(&NewTableID, m_lDBIDType, wcslen(m_pTable->GetTableName())), S_OK);
|
|
TESTC_(MakeNewColumnID(&ColumnDesc.dbcid, m_lDBIDType, wcslen(m_Col.GetColName())), S_OK);
|
|
|
|
// start the transaction
|
|
TESTC_(pITransactionLocal->StartTransaction(ISOLATIONLEVEL_READUNCOMMITTED, 0, NULL, NULL), S_OK);
|
|
|
|
|
|
if( V_I4(&vSupportedTxnDDL) == DBPROPVAL_TC_DML )
|
|
{
|
|
//check for XACT_E_XTIONEXISTS
|
|
TESTC_(m_pIAlterTable->AlterColumn(&pTable->GetTableID(), col.GetColID(), DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), XACT_E_XTIONEXISTS);
|
|
TESTC_(m_pIAlterTable->AlterTable(&pTable->GetTableID(), &NewTableID, 0, NULL), XACT_E_XTIONEXISTS);
|
|
}
|
|
else if ( V_I4(&vSupportedTxnDDL) == DBPROPVAL_TC_DDL_IGNORE ||
|
|
V_I4(&vSupportedTxnDDL) == DBPROPVAL_TC_ALL ||
|
|
V_I4(&vSupportedTxnDDL) == DBPROPVAL_TC_DDL_COMMIT)
|
|
{
|
|
// change table and column IDs
|
|
TESTC_(m_pIAlterTable->AlterColumn(&pTable->GetTableID(), col.GetColID(), DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), S_OK);
|
|
TESTC_(m_pIAlterTable->AlterTable(&pTable->GetTableID(), &NewTableID, 0, NULL), S_OK);
|
|
}
|
|
else if( V_I4(&vSupportedTxnDDL) == DBPROPVAL_TC_DDL_LOCK )
|
|
{
|
|
// Change the Column ID - this should lock the table
|
|
TESTC_(m_pIAlterTable->AlterColumn(&pTable->GetTableID(), col.GetColID(), DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc), S_OK);
|
|
|
|
// Check that the table is locked from a different session
|
|
TESTC_(pIAlterTable->AlterTable(&pTable->GetTableID(), &m_pTable->GetTableID(), 0, NULL), DB_E_TABLEINUSE);
|
|
|
|
// Commit
|
|
TESTC_(pITransactionLocal->Commit(TRUE, 0, 0), S_OK);
|
|
|
|
// Change the Table ID - this should lock the table
|
|
TESTC_(m_pIAlterTable->AlterTable(&pTable->GetTableID(), &NewTableID, 0, NULL), S_OK);
|
|
|
|
// Check that the table is locked from a different session
|
|
TESTC_(pIAlterTable->AlterTable(&pTable->GetTableID(), &NewTableID, 0, NULL), DB_E_TABLEINUSE);
|
|
}
|
|
|
|
// Commit the transaction and don't retain
|
|
if (DBPROPVAL_TC_DDL_COMMIT != vSupportedTxnDDL.lVal)
|
|
{
|
|
TESTC_(pITransactionLocal->Commit(FALSE, 0, 0), S_OK);
|
|
}
|
|
else
|
|
{
|
|
TESTC_(pITransactionLocal->Commit(FALSE, 0, 0), XACT_E_NOTRANSACTION );
|
|
}
|
|
|
|
|
|
if( V_I4(&vSupportedTxnDDL) == DBPROPVAL_TC_DML ||
|
|
V_I4(&vSupportedTxnDDL) == DBPROPVAL_TC_DDL_IGNORE )
|
|
{
|
|
// Check that the table and column names are not changed
|
|
TESTC_(pTable->DoesTableExist(&NewTableID, &fExists), S_OK);
|
|
TESTC(fExists == FALSE);
|
|
TESTC(CompareColumnMetaData(1, 0, NULL, pTable));
|
|
}
|
|
else
|
|
{
|
|
|
|
// check that the table and column names have changed
|
|
TESTC_(pTable->DoesTableExist(&NewTableID, &fExists), S_OK);
|
|
TESTC(fExists == TRUE);
|
|
|
|
// Restore the table ID
|
|
TESTC_(AlterTable(&NewTableID, &pTable->GetTableID()), S_OK);
|
|
|
|
TESTC(CompareColumnMetaData(1, DBCOLUMNDESCFLAGS_DBCID, &ColumnDesc, pTable));
|
|
}
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIAlterTable);
|
|
SAFE_RELEASE(pITransactionLocal);
|
|
|
|
if( pTable )
|
|
{
|
|
pTable->DropTable();
|
|
SAFE_DELETE(pTable);
|
|
}
|
|
|
|
ReleaseDBID(&ColumnDesc.dbcid, FALSE);
|
|
ReleaseDBID(&NewTableID, FALSE);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(64)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Bad prop option
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_64()
|
|
{
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_BADOPTION,
|
|
DBPROP_COL_SEED, DBPROPSET_COLUMN, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL+1);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(65)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Non column prop set REQUIRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_65()
|
|
{
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_NOTSUPPORTED,
|
|
DBPROP_TBL_TEMPTABLE, DBPROPSET_TABLE, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(66)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Non column prop set OPTIONAL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_66()
|
|
{
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_NOTSUPPORTED,
|
|
DBPROP_COL_ISLONG, DBPROPSET_SESSION, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(67)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Mismatch in property vt type. REQUIRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_67()
|
|
{
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_BADVALUE,
|
|
DBPROP_COL_UNIQUE, DBPROPSET_COLUMN, (void *)L"No", DBTYPE_BSTR, DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(68)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Mismatch in property vt type. OPTIONAL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_68()
|
|
{
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_NOTSET,
|
|
DBPROP_COL_DESCRIPTION, DBPROPSET_COLUMN, (void *)LONG_MAX, DBTYPE_I4, DBPROPOPTIONS_OPTIONAL);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(69)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid property value. REQUIRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_69()
|
|
{
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_BADVALUE,
|
|
DBPROP_COL_NULLABLE, DBPROPSET_COLUMN, (void *)1, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(70)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid property value. OPTIONAL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_70()
|
|
{
|
|
VARIANT vt;
|
|
|
|
// Invalid default value
|
|
VariantInit(&vt);
|
|
V_VT(&vt) = VT_VARIANT;
|
|
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_NOTSET,
|
|
DBPROP_COL_DEFAULT, DBPROPSET_COLUMN, (void *)&vt, DBTYPE_VARIANT, DBPROPOPTIONS_OPTIONAL);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(71)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc colid was not DB_NULLID. OPTIONAL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_71()
|
|
{
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_BADCOLUMN,
|
|
DBPROP_COL_NULLABLE, DBPROPSET_COLUMN, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED, m_pTable->GetTableID());
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(72)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc colid was not DB_NULLID. REQUIRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAlterColumn::Variation_72()
|
|
{
|
|
return VerifyAlterInvalidColumnProperties(m_pTable, DBPROPSTATUS_NOTSET,
|
|
DBPROP_COL_AUTOINCREMENT, DBPROPSET_COLUMN, (void *)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL, m_pTable->GetTableID());
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAlterColumn::Terminate()
|
|
{
|
|
SAFE_DELETE(m_pSchema);
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCIAlterTable::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCZombie)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCZombie - Test the Zombie states of IAlterTable
|
|
//| Created: 09-01-99
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCZombie::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CTransaction::Init())
|
|
// }}
|
|
{
|
|
//register interface to be tested
|
|
if(RegisterInterface(SESSION_INTERFACE, IID_IAlterTable))
|
|
return TRUE;
|
|
}
|
|
|
|
//Not all providers have to support transactions
|
|
//If a required interface, an error would ahve been posted by VerifyInterface
|
|
TEST_PROVIDER(m_pITransactionLocal != NULL);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ABORT with fRetaining TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_1()
|
|
{
|
|
TBEGIN
|
|
IAlterTable * pIAlterTable = NULL;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IAlterTable interface
|
|
TESTC(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIAlterTable))
|
|
TESTC(pIAlterTable != NULL)
|
|
|
|
//Abort the Transaction with fRetaining==TRUE
|
|
TESTC(GetAbort(TRUE))
|
|
|
|
//Verify we still can use IAlterTable after an ABORT
|
|
TESTC_(pIAlterTable->AlterTable(&m_pCTable->GetTableID(), NULL, 0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIAlterTable);
|
|
|
|
CleanUpTransaction(S_OK);
|
|
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ABORT with fRetaining FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_2()
|
|
{
|
|
TBEGIN
|
|
IAlterTable * pIAlterTable = NULL;
|
|
|
|
//Start the Transaction
|
|
TESTC(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIAlterTable))
|
|
TESTC(pIAlterTable!=NULL)
|
|
|
|
//Abort the Transaction with fRetaining==FALSE
|
|
TESTC(GetAbort(FALSE))
|
|
|
|
//Verify we still can use IAlterTable after an ABORT
|
|
TESTC_(pIAlterTable->AlterTable(&m_pCTable->GetTableID(), NULL, 0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIAlterTable);
|
|
CleanUpTransaction(XACT_E_NOTRANSACTION); //No longer in a transaction
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc COMMIT with fRetaining TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_3()
|
|
{
|
|
TBEGIN
|
|
IAlterTable * pIAlterTable = NULL;
|
|
|
|
//Start the Transaction
|
|
TESTC(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIAlterTable))
|
|
TESTC(pIAlterTable != NULL)
|
|
|
|
//Abort the Transaction with fRetaining==TRUE
|
|
TESTC(GetCommit(TRUE))
|
|
|
|
//Verify we still can use IAlterTable after an ABORT
|
|
TESTC_(pIAlterTable->AlterTable(&m_pCTable->GetTableID(), NULL, 0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIAlterTable);
|
|
CleanUpTransaction(S_OK);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc COMMIT with fRetaining FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_4()
|
|
{
|
|
TBEGIN
|
|
IAlterTable * pIAlterTable = NULL;
|
|
|
|
//Start the Transaction
|
|
TESTC(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIAlterTable))
|
|
TESTC(pIAlterTable != NULL)
|
|
|
|
//Abort the Transaction with fRetaining==FALSE
|
|
TESTC(GetCommit(FALSE))
|
|
|
|
//Verify we still can use IAlterTable after an ABORT
|
|
TESTC_(pIAlterTable->AlterTable(&m_pCTable->GetTableID(), NULL, 0, NULL), S_OK);
|
|
|
|
CLEANUP:
|
|
|
|
SAFE_RELEASE(pIAlterTable);
|
|
CleanUpTransaction(XACT_E_NOTRANSACTION); //No longer in a transaction
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCZombie::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTransaction::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|