//-------------------------------------------------------------------- // 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; iPropSetcProperties && 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