2252 lines
63 KiB
C++
2252 lines
63 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright (C) 1995-2000 Microsoft Corporation
|
|
//
|
|
// @doc
|
|
//
|
|
// @module IRowChange.cpp | This module tests the OLEDB IRowChange interface
|
|
//
|
|
|
|
#include "MODStandard.hpp" // Standard headers
|
|
#include "IRowChange.h" // IRowChange header
|
|
#include "ExtraLib.h"
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Module Values
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// {{ TCW_MODULE_GLOBALS
|
|
DECLARE_MODULE_CLSID = { 0x7dbea520, 0x3ec1, 0x11d2, { 0xa9, 0x8f, 0x00, 0xc0, 0x4f, 0x94, 0xa7, 0x17} };
|
|
DECLARE_MODULE_NAME("IRowChange");
|
|
DECLARE_MODULE_OWNER("Microsoft");
|
|
DECLARE_MODULE_DESCRIP("IRowChange interface test");
|
|
DECLARE_MODULE_VERSION(838086926);
|
|
// TCW_WizardVersion(2)
|
|
// TCW_Automation(False)
|
|
// }} TCW_MODULE_GLOBALS_END
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Globals
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
ULONG cInterfaceIIDs = 0;
|
|
INTERFACEMAP* rgInterfaceIIDs = NULL;
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level initialization routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleInit(CThisTestModule * pThisTestModule)
|
|
{
|
|
//Obtain the Interface IIDs for the Row object
|
|
if(GetInterfaceArray(ROW_INTERFACE, &cInterfaceIIDs, &rgInterfaceIIDs))
|
|
return CommonModuleInit(pThisTestModule, IID_IRowChange, SIZEOF_TABLE, ROW_INTERFACE);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level termination routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleTerminate(CThisTestModule * pThisTestModule)
|
|
{
|
|
return CommonModuleTerminate(pThisTestModule);
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
class TCIRowChange : public CRowsetChange
|
|
{
|
|
public:
|
|
//constructors
|
|
TCIRowChange(WCHAR* pwszTestCaseName = INVALID(WCHAR*));
|
|
virtual ~TCIRowChange();
|
|
|
|
//methods
|
|
virtual BOOL Init();
|
|
virtual BOOL Terminate();
|
|
|
|
//IRowChange
|
|
virtual BOOL VerifySetColumns
|
|
(
|
|
CRowObject* pCRowObject,
|
|
DBCOUNTITEM iRow,
|
|
DBORDINAL cColAccess,
|
|
DBCOLUMNACCESS* rgColAccess
|
|
);
|
|
|
|
virtual BOOL VerifySetColumns
|
|
(
|
|
CRowObject* pCRowObject,
|
|
DBCOUNTITEM iRow,
|
|
ECOLS_BOUND eColsToBind = UPDATEABLE_NONINDEX_COLS_BOUND,
|
|
BLOBTYPE dwBlobType = NO_BLOB_COLS,
|
|
ECOLUMNORDER eBindingOrder = FORWARD,
|
|
ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF,
|
|
DBTYPE dwModifier = DBTYPE_EMPTY,
|
|
DBORDINAL cColsToBind = 0,
|
|
DBORDINAL* rgColsToBind = NULL,
|
|
DBPART dwPart = DBPART_VALUE|DBPART_STATUS|DBPART_LENGTH
|
|
);
|
|
|
|
virtual BOOL VerifySetColumnsAllRows
|
|
(
|
|
CRowsetChange* pCRowset,
|
|
ECOLS_BOUND eColsToBind = UPDATEABLE_NONINDEX_COLS_BOUND,
|
|
BLOBTYPE dwBlobType = NO_BLOB_COLS,
|
|
ECOLUMNORDER eBindingOrder = FORWARD,
|
|
ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF,
|
|
DBTYPE dwModifier = DBTYPE_EMPTY,
|
|
DBORDINAL cColsToBind = 0,
|
|
DBORDINAL* rgColsToBind = NULL,
|
|
DBPART dwPart = DBPART_VALUE|DBPART_STATUS|DBPART_LENGTH
|
|
);
|
|
|
|
//Thread Methods
|
|
static ULONG WINAPI Thread_VerifySetColumns(LPVOID pv);
|
|
|
|
//Interface
|
|
virtual IRowChange* const pIRowChange();
|
|
|
|
//Data
|
|
CRowObject* m_pCRowObject;
|
|
IRowChange* m_pIRowChange;
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::TCIRowChange
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
TCIRowChange::TCIRowChange(WCHAR * wstrTestCaseName) : CRowsetChange(wstrTestCaseName)
|
|
{
|
|
m_pCRowObject = NULL;
|
|
m_pIRowChange = NULL;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::~TCIRowChange
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
TCIRowChange::~TCIRowChange()
|
|
{
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::Init
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowChange::Init()
|
|
{
|
|
TBEGIN
|
|
HROW hRow = NULL;
|
|
|
|
//Create the new row object
|
|
m_pCRowObject = new CRowObject;
|
|
TESTC(m_pCRowObject != NULL);
|
|
|
|
TESTC(CRowsetChange::Init());
|
|
|
|
//Create the Rowset object
|
|
//CANHOLDROWS is a requireed level 0 property
|
|
TESTC_(CreateRowset(DBPROP_CANHOLDROWS), S_OK);
|
|
|
|
//Obtain the First row...
|
|
TESTC_(GetNextRows(&hRow),S_OK);
|
|
|
|
//Now create the row object.
|
|
TEST2C_(m_pCRowObject->CreateRowObject(pIRowset(), hRow), S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
|
|
//Now obtain our IRowChange interface.
|
|
TESTC(VerifyInterface(m_pCRowObject->pIRow(), IID_IRowChange, ROW_INTERFACE, (IUnknown**)&m_pIRowChange));
|
|
|
|
CLEANUP:
|
|
ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::Terminate
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowChange::Terminate()
|
|
{
|
|
SAFE_RELEASE(m_pIRowChange);
|
|
SAFE_DELETE(m_pCRowObject);
|
|
return CRowsetChange::Terminate();
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::VerifySetColumns
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowChange::VerifySetColumns
|
|
(
|
|
CRowObject* pCRowObject,
|
|
DBCOUNTITEM iRow,
|
|
DBORDINAL cColAccess,
|
|
DBCOLUMNACCESS* rgColAccess
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
//Create the Data for SetColumns
|
|
TESTC_(hr = pCRowObject->FillColAccess(pTable(), cColAccess, rgColAccess, iRow),S_OK);
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(hr = pCRowObject->SetColumns(cColAccess, rgColAccess),S_OK);
|
|
|
|
//IRow::GetColumns
|
|
TESTC_(hr = pCRowObject->GetColumns(cColAccess, rgColAccess),S_OK);
|
|
|
|
//Compare Data for this row object
|
|
if(!pCRowObject->CompareColAccess(cColAccess, rgColAccess, iRow, pTable()))
|
|
{
|
|
//Data incorrect for this row!
|
|
TERROR("Data was incorrect for row " << iRow);
|
|
QTESTC(FALSE);
|
|
}
|
|
|
|
FreeColAccess(cColAccess, rgColAccess, FALSE);
|
|
|
|
CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::VerifySetColumns
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowChange::VerifySetColumns
|
|
(
|
|
CRowObject* pCRowObject,
|
|
DBCOUNTITEM iRow,
|
|
ECOLS_BOUND eColsToBind,
|
|
BLOBTYPE dwBlobType,
|
|
ECOLUMNORDER eBindingOrder,
|
|
ECOLS_BY_REF eColsByRef,
|
|
DBTYPE dwModifier,
|
|
DBORDINAL cColsToBind,
|
|
DBORDINAL* rgColsToBind,
|
|
DBPART dwPart
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
DBORDINAL cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
void* pData = NULL;
|
|
|
|
//Create the ColAccess Structures...
|
|
TESTC_(hr = pCRowObject->CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, eColsToBind, dwBlobType, eBindingOrder, eColsByRef, dwModifier, cColsToBind, rgColsToBind, dwPart),S_OK);
|
|
|
|
//Verify SetColumns
|
|
QTESTC(VerifySetColumns(pCRowObject, iRow, cColAccess, rgColAccess));
|
|
|
|
CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::VerifySetColumnsAllRows
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowChange::VerifySetColumnsAllRows
|
|
(
|
|
CRowsetChange* pCRowset,
|
|
ECOLS_BOUND eColsToBind,
|
|
BLOBTYPE dwBlobType,
|
|
ECOLUMNORDER eBindingOrder,
|
|
ECOLS_BY_REF eColsByRef,
|
|
DBTYPE dwModifier,
|
|
DBORDINAL cColsToBind,
|
|
DBORDINAL* rgColsToBind,
|
|
DBPART dwPart
|
|
)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
DBCOUNTITEM iRow,cRowsObtained = 0;
|
|
HROW* rghRows = NULL;
|
|
CRowsetChange RowsetA;
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
|
|
//Restart the position.
|
|
if(pCRowset)
|
|
{
|
|
TEST2C_(hr = pCRowset->RestartPosition(),S_OK, DB_E_CANNOTRESTART);
|
|
}
|
|
|
|
//Default rowset
|
|
//Some providers may not be able to restart due to live data stream...
|
|
if(pCRowset == NULL || hr==DB_E_CANNOTRESTART)
|
|
{
|
|
pCRowset = &RowsetA;
|
|
|
|
//May require IRowsetLocate to position on Blobs
|
|
if(dwBlobType != NO_BLOB_COLS)
|
|
pCRowset->SetSettableProperty(DBPROP_IRowsetLocate);
|
|
TESTC_(pCRowset->CreateRowset(),S_OK);
|
|
}
|
|
|
|
//See if we are in bufferred mode
|
|
VerifyInterface(pCRowset->pIRowset(), IID_IRowsetUpdate, ROWSET_INTERFACE, (IUnknown**)&pIRowsetUpdate);
|
|
|
|
//loop through the rowset, retrieve one row at a time
|
|
for(iRow=1; iRow<=pCRowset->m_ulTableRows; iRow++)
|
|
{
|
|
//GetNextRow
|
|
CRowObject RowObjectA;
|
|
TESTC_(pCRowset->GetNextRows(0, 1, &cRowsObtained, &rghRows),S_OK);
|
|
|
|
//Create the row object from this row
|
|
TEST2C_(RowObjectA.CreateRowObject(pCRowset->pIRowset(), rghRows[0]), S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
|
|
//Verify Row Object
|
|
QTESTC(VerifySetColumns(&RowObjectA, iRow, eColsToBind, dwBlobType, eBindingOrder, eColsByRef, dwModifier, cColsToBind, rgColsToBind, dwPart));
|
|
|
|
//release the row handle
|
|
TESTC_(pCRowset->ReleaseRows(cRowsObtained, rghRows),S_OK);
|
|
PROVIDER_FREE(rghRows);
|
|
|
|
//If the rowset is in buffered mode, it will require an Update, or Undo
|
|
//before the change really takes effect.
|
|
if(pIRowsetUpdate)
|
|
TESTC_(pIRowsetUpdate->Update(NULL, 0, NULL, NULL, NULL, NULL),S_OK);
|
|
}
|
|
|
|
CLEANUP:
|
|
if(pCRowset)
|
|
pCRowset->ReleaseRows(cRowsObtained, rghRows);
|
|
PROVIDER_FREE(rghRows);
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::Thread_VerifySetColumns
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
ULONG TCIRowChange::Thread_VerifySetColumns(void* pv)
|
|
{
|
|
THREAD_BEGIN
|
|
|
|
//Thread Stack Variables
|
|
TCIRowChange* pThis = (TCIRowChange*)THREAD_FUNC;
|
|
CRowObject* pCRowObject = (CRowObject*)THREAD_ARG1;
|
|
ASSERT(pThis && pCRowObject);
|
|
|
|
ThreadSwitch(); //Let the other thread(s) catch up
|
|
|
|
//IRowChange::SetColumns
|
|
QTESTC(pThis->VerifySetColumns(pCRowObject, FIRST_ROW, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
|
|
ThreadSwitch(); //Let the other thread(s) catch up
|
|
|
|
CLEANUP:
|
|
THREAD_RETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowChange::pIRowChange
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
IRowChange* const TCIRowChange::pIRowChange()
|
|
{
|
|
ASSERT(m_pIRowChange);
|
|
return m_pIRowChange;
|
|
}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCIRowChange_IUnknown)
|
|
//*-----------------------------------------------------------------------
|
|
// @class IRowChange IUnknown scenarios
|
|
//
|
|
class TCIRowChange_IUnknown : public TCIRowChange {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCIRowChange_IUnknown,TCIRowChange);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember IUnknown - QI Mandatory Interfaces
|
|
int Variation_1();
|
|
// @cmember IUnknown - QI Optional Interfaces
|
|
int Variation_2();
|
|
// @cmember IUnknown - AddRef / Release
|
|
int Variation_3();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCIRowChange_IUnknown)
|
|
#define THE_CLASS TCIRowChange_IUnknown
|
|
BEG_TEST_CASE(TCIRowChange_IUnknown, TCIRowChange, L"IRowChange IUnknown scenarios")
|
|
TEST_VARIATION(1, L"IUnknown - QI Mandatory Interfaces")
|
|
TEST_VARIATION(2, L"IUnknown - QI Optional Interfaces")
|
|
TEST_VARIATION(3, L"IUnknown - AddRef / Release")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCIRowChange_SetColumns)
|
|
//*-----------------------------------------------------------------------
|
|
// @class IRowChange::SetColumns
|
|
//
|
|
class TCIRowChange_SetColumns : public TCIRowChange {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCIRowChange_SetColumns,TCIRowChange);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember SetColumns - All columns - no BLOBs
|
|
int Variation_1();
|
|
// @cmember SetColumns - All Columns - BLOBs
|
|
int Variation_2();
|
|
// @cmember SetColumns - 0 columns - no-op
|
|
int Variation_3();
|
|
// @cmember SetColumns - same column bound numerous times
|
|
int Variation_4();
|
|
// @cmember SetColumns - BLOB Columns only
|
|
int Variation_5();
|
|
// @cmember SetColumns - Each Column Seperatly
|
|
int Variation_6();
|
|
// @cmember SetColumns - Asking for just Rowset columns
|
|
int Variation_7();
|
|
// @cmember SetColumns - Asking for just Extra Row Columns
|
|
int Variation_8();
|
|
// @cmember SetColumns - IUnknown Columns - native
|
|
int Variation_9();
|
|
// @cmember Empty
|
|
int Variation_10();
|
|
// @cmember SetColumns - Not Binding Value for all columns, pData is NULL - DB_E_ERRORSOCCURRED
|
|
int Variation_11();
|
|
// @cmember SetColumns - Not Binding Value for some columns, pData is NULL - DB_S_ERRORSOCCURRED
|
|
int Variation_12();
|
|
// @cmember SetColumns - Not Binding Value for ISNULL columns, pData is NULL - S_OK
|
|
int Variation_13();
|
|
// @cmember SetColumns - Not Binding Value for BLOB columns, pData is NULL - S_OK
|
|
int Variation_14();
|
|
// @cmember SetColumns - Binding all columns, even read-only columns - DB_S_ERRORSOCCURRED
|
|
int Variation_15();
|
|
// @cmember Empty
|
|
int Variation_16();
|
|
// @cmember Boundary - Some valid, some non-existent columns - DB_S_ERRORSOCCURRED
|
|
int Variation_17();
|
|
// @cmember Boundary - All non-existent columns - DB_E_ERRORSOCCURRED
|
|
int Variation_18();
|
|
// @cmember Boundary - No Vector Columns - S_OK
|
|
int Variation_19();
|
|
// @cmember Boundary - No Vectors and Non-Existent Columns - DB_E_ERRORSOCCURRED
|
|
int Variation_20();
|
|
// @cmember Boundary - Only Vector Columns - S_OK
|
|
int Variation_21();
|
|
// @cmember Boundary - Only Non-Existent Vector Columns - DB_E_ERRORSOCCURRED
|
|
int Variation_22();
|
|
// @cmember Boundary - Valid Vectors and Non-Existent Columns - DB_S_ERRORSOCCURRED
|
|
int Variation_23();
|
|
// @cmember Boundary - Valid Non-Vectors and Non-Existent Vector Columns - DB_S_ERRORSOCCURRED
|
|
int Variation_24();
|
|
// @cmember Empty
|
|
int Variation_25();
|
|
// @cmember Status - DBSTATUS_S_ISNULL
|
|
int Variation_26();
|
|
// @cmember Status - DBSTATUS_S_DEFAULT
|
|
int Variation_27();
|
|
// @cmember Status - DBSTATUS_S_IGNORE
|
|
int Variation_28();
|
|
// @cmember Empty
|
|
int Variation_29();
|
|
// @cmember Buffered Mode - All Columns - no BLOBs
|
|
int Variation_30();
|
|
// @cmember Buffered Mode - All Columns - BLOBs
|
|
int Variation_31();
|
|
// @cmember Buffered Mode - All Columns - Just extra columns
|
|
int Variation_32();
|
|
// @cmember Empty
|
|
int Variation_33();
|
|
// @cmember Multiple Row Object - same row
|
|
int Variation_34();
|
|
// @cmember Multiple Row Object - different rows
|
|
int Variation_35();
|
|
// @cmember Empty
|
|
int Variation_36();
|
|
// @cmember Threads - SetColumns seperate threads [same row object]
|
|
int Variation_37();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCIRowChange_SetColumns)
|
|
#define THE_CLASS TCIRowChange_SetColumns
|
|
BEG_TEST_CASE(TCIRowChange_SetColumns, TCIRowChange, L"IRowChange::SetColumns")
|
|
TEST_VARIATION(1, L"SetColumns - All columns - no BLOBs")
|
|
TEST_VARIATION(2, L"SetColumns - All Columns - BLOBs")
|
|
TEST_VARIATION(3, L"SetColumns - 0 columns - no-op")
|
|
TEST_VARIATION(4, L"SetColumns - same column bound numerous times")
|
|
TEST_VARIATION(5, L"SetColumns - BLOB Columns only")
|
|
TEST_VARIATION(6, L"SetColumns - Each Column Seperatly")
|
|
TEST_VARIATION(7, L"SetColumns - Asking for just Rowset columns")
|
|
TEST_VARIATION(8, L"SetColumns - Asking for just Extra Row Columns")
|
|
TEST_VARIATION(9, L"SetColumns - IUnknown Columns - native")
|
|
TEST_VARIATION(10, L"Empty")
|
|
TEST_VARIATION(11, L"SetColumns - Not Binding Value for all columns, pData is NULL - DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(12, L"SetColumns - Not Binding Value for some columns, pData is NULL - DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(13, L"SetColumns - Not Binding Value for ISNULL columns, pData is NULL - S_OK")
|
|
TEST_VARIATION(14, L"SetColumns - Not Binding Value for BLOB columns, pData is NULL - S_OK")
|
|
TEST_VARIATION(15, L"SetColumns - Binding all columns, even read-only columns - DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(16, L"Empty")
|
|
TEST_VARIATION(17, L"Boundary - Some valid, some non-existent columns - DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(18, L"Boundary - All non-existent columns - DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(19, L"Boundary - No Vector Columns - S_OK")
|
|
TEST_VARIATION(20, L"Boundary - No Vectors and Non-Existent Columns - DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(21, L"Boundary - Only Vector Columns - S_OK")
|
|
TEST_VARIATION(22, L"Boundary - Only Non-Existent Vector Columns - DB_E_ERRORSOCCURRED")
|
|
TEST_VARIATION(23, L"Boundary - Valid Vectors and Non-Existent Columns - DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(24, L"Boundary - Valid Non-Vectors and Non-Existent Vector Columns - DB_S_ERRORSOCCURRED")
|
|
TEST_VARIATION(25, L"Empty")
|
|
TEST_VARIATION(26, L"Status - DBSTATUS_S_ISNULL")
|
|
TEST_VARIATION(27, L"Status - DBSTATUS_S_DEFAULT")
|
|
TEST_VARIATION(28, L"Status - DBSTATUS_S_IGNORE")
|
|
TEST_VARIATION(29, L"Empty")
|
|
TEST_VARIATION(30, L"Buffered Mode - All Columns - no BLOBs")
|
|
TEST_VARIATION(31, L"Buffered Mode - All Columns - BLOBs")
|
|
TEST_VARIATION(32, L"Buffered Mode - All Columns - Just extra columns")
|
|
TEST_VARIATION(33, L"Empty")
|
|
TEST_VARIATION(34, L"Multiple Row Object - same row")
|
|
TEST_VARIATION(35, L"Multiple Row Object - different rows")
|
|
TEST_VARIATION(36, L"Empty")
|
|
TEST_VARIATION(37, L"Threads - SetColumns seperate threads [same row object]")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCTransactions)
|
|
//*-----------------------------------------------------------------------
|
|
// @class IRowChange inside Transactions
|
|
//
|
|
class TCTransactions : public CTransaction {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCTransactions,CTransaction);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
//Helpers
|
|
virtual BOOL VerifyTransaction(BOOL fCommit, BOOL fRetaining);
|
|
|
|
// {{ 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(TCTransactions)
|
|
#define THE_CLASS TCTransactions
|
|
BEG_TEST_CASE(TCTransactions, CTransaction, L"IRowChange inside Transactions")
|
|
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
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Test Case Section
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// }} END_DECLARE_TEST_CASES()
|
|
|
|
// {{ TCW_TESTMODULE(ThisModule)
|
|
TEST_MODULE(3, ThisModule, gwszModuleDescrip)
|
|
TEST_CASE(1, TCIRowChange_IUnknown)
|
|
TEST_CASE(2, TCIRowChange_SetColumns)
|
|
TEST_CASE(3, TCTransactions)
|
|
END_TEST_MODULE()
|
|
// }} TCW_TESTMODULE_END
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCTransactionsVerifyTransaction
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCTransactions::VerifyTransaction(BOOL fCommit, BOOL fRetaining)
|
|
{
|
|
HROW hRow;
|
|
IGetRow* pIGetRow = NULL;
|
|
BOOL fPreserving = FALSE;
|
|
CRowset RowsetA;
|
|
CRowObject RowObjectA;
|
|
|
|
//start a transaction
|
|
TESTC(StartTransaction(SELECT_ALLFROMTBL, (IUnknown**)&pIGetRow, 0, NULL));
|
|
TESTC_(RowsetA.CreateRowset(pIGetRow),S_OK);
|
|
|
|
//Obtain a row object - before we commit/abort the transaction
|
|
TESTC_(RowsetA.GetNextRows(&hRow),S_OK);
|
|
TESTC_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow),S_OK);
|
|
|
|
//FillColAccess (before we commit/abort the transaction
|
|
TESTC_(RowObjectA.FillColAccess(RowsetA.pTable(), RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess, FIRST_ROW),S_OK);
|
|
|
|
//commit the transaction with fRetaining==TRUE
|
|
if(fCommit)
|
|
{
|
|
TESTC(GetCommit(fRetaining))
|
|
fPreserving = m_fCommitPreserve;
|
|
}
|
|
else
|
|
{
|
|
TESTC(GetAbort(fRetaining))
|
|
fPreserving = m_fAbortPreserve;
|
|
}
|
|
|
|
if(fPreserving)
|
|
{
|
|
//fully functional
|
|
|
|
//IRow::SetColumns
|
|
TESTC(RowObjectA.SetColumns(RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess));
|
|
|
|
//IRow::GetColumns
|
|
TESTC_(RowObjectA.GetColumns(RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess),S_OK);
|
|
|
|
//Compare Data for this row object
|
|
TESTC(RowObjectA.CompareColAccess(RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess, FIRST_ROW, RowsetA.pTable()));
|
|
}
|
|
else
|
|
{
|
|
//zombie
|
|
|
|
//IRow::SetColumns
|
|
TESTC_(RowObjectA.SetColumns(RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess),E_UNEXPECTED);
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIGetRow);
|
|
|
|
//clean up.
|
|
CleanUpTransaction(fRetaining ? S_OK : XACT_E_NOTRANSACTION);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCIRowChange_IUnknown)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCIRowChange_IUnknown - IRowChange IUnknown scenarios
|
|
//| Created: 8/5/98
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCIRowChange_IUnknown::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCIRowChange::Init())
|
|
// }}
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IUnknown - QI Mandatory Interfaces
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_IUnknown::Variation_1()
|
|
{
|
|
//Do some default IUnknown interface testing
|
|
return DefaultObjectTesting(pIRowChange(), ROW_INTERFACE);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IUnknown - QI Optional Interfaces
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_IUnknown::Variation_2()
|
|
{
|
|
//Do some default IUnknown interface testing
|
|
return DefaultObjectTesting(pIRowChange(), ROW_INTERFACE);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IUnknown - AddRef / Release
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_IUnknown::Variation_3()
|
|
{
|
|
//Do some default IUnknown interface testing
|
|
return DefaultObjectTesting(pIRowChange(), ROW_INTERFACE);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCIRowChange_IUnknown::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCIRowChange::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCIRowChange_SetColumns)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCIRowChange_SetColumns - IRowChange::SetColumns
|
|
//| Created: 8/5/98
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCIRowChange_SetColumns::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCIRowChange::Init())
|
|
// }}
|
|
{
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - All columns - no BLOBs
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_1()
|
|
{
|
|
TBEGIN
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(this, UPDATEABLE_NONINDEX_COLS_BOUND));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - All Columns - BLOBs
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(this, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - 0 columns - no-op
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_3()
|
|
{
|
|
TBEGIN
|
|
|
|
//SetColumns - with (0 NULL)
|
|
TESTC(VerifySetColumnsAllRows(this, USE_COLS_TO_BIND_ARRAY, BLOB_LONG, FORWARD,
|
|
NO_COLS_BY_REF, DBTYPE_EMPTY, 0, NULL));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - same column bound numerous times
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_4()
|
|
{
|
|
TBEGIN
|
|
IColumnsInfo* pIColumnsInfo = NULL;
|
|
DBORDINAL i,cColumns=0;
|
|
DBCOLUMNINFO* rgColumnInfo = NULL;
|
|
WCHAR* pStringBuffer = NULL;
|
|
DBORDINAL cColOrds = 0;
|
|
DBORDINAL* rgColOrds = NULL;
|
|
|
|
//Use a new rowset, and ask for a non-forward-only cursor,
|
|
//so we can obtain the data multiple times.
|
|
CRowsetChange RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_OTHERUPDATEDELETE)==S_OK);
|
|
|
|
//Get the ColumnInfo
|
|
TESTC(VerifyInterface(pIRowChange(), IID_IColumnsInfo, ROW_INTERFACE, (IUnknown**)&pIColumnsInfo));
|
|
TESTC_(pIColumnsInfo->GetColumnInfo(&cColumns, &rgColumnInfo, &pStringBuffer),S_OK);
|
|
SAFE_ALLOC(rgColOrds, DBORDINAL, cColumns);
|
|
|
|
//Loop through each column seperatly...
|
|
for(i=0; i<cColumns; i++)
|
|
{
|
|
//Fill in the Col Ordinals with numerous duplicates
|
|
cColOrds = 0;
|
|
for(ULONG iDup=0; iDup<i; iDup++)
|
|
{
|
|
if(rgColumnInfo[i].dwFlags & DBCOLUMNFLAGS_WRITE)
|
|
{
|
|
rgColOrds[iDup] = rgColumnInfo[i].iOrdinal;
|
|
cColOrds++;
|
|
}
|
|
}
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(&RowsetA, USE_COLS_TO_BIND_ARRAY, BLOB_LONG, FORWARD,
|
|
NO_COLS_BY_REF, DBTYPE_EMPTY, cColOrds, rgColOrds));
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(rgColumnInfo);
|
|
SAFE_FREE(pStringBuffer);
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
SAFE_FREE(rgColOrds);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - BLOB Columns only
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_5()
|
|
{
|
|
TBEGIN
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(this, BLOB_COLS_BOUND, BLOB_LONG));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - Each Column Seperatly
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_6()
|
|
{
|
|
TBEGIN
|
|
IColumnsInfo* pIColumnsInfo = NULL;
|
|
DBORDINAL iCol,cColumns=0;
|
|
DBCOLUMNINFO* rgColumnInfo = NULL;
|
|
WCHAR* pStringBuffer = NULL;
|
|
|
|
//Get the ColumnInfo
|
|
TESTC(VerifyInterface(pIRowChange(), IID_IColumnsInfo, ROW_INTERFACE, (IUnknown**)&pIColumnsInfo));
|
|
TESTC_(pIColumnsInfo->GetColumnInfo(&cColumns, &rgColumnInfo, &pStringBuffer),S_OK);
|
|
|
|
//Loop through each column seperatly...
|
|
for(iCol=0; iCol<cColumns; iCol++)
|
|
{
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
if(rgColumnInfo[iCol].dwFlags & DBCOLUMNFLAGS_WRITE)
|
|
{
|
|
if(!VerifySetColumnsAllRows(this, USE_COLS_TO_BIND_ARRAY, BLOB_LONG, FORWARD,NO_COLS_BY_REF, DBTYPE_EMPTY, 1, &rgColumnInfo[iCol].iOrdinal))
|
|
{
|
|
//Data incorrect for this column!
|
|
TERROR("Data was incorrect for this column Ordinal " << rgColumnInfo[iCol].iOrdinal);
|
|
}
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(rgColumnInfo);
|
|
SAFE_FREE(pStringBuffer);
|
|
SAFE_RELEASE(pIColumnsInfo);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - Asking for just Rowset columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_7()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
DBORDINAL cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
HROW hRow = NULL;
|
|
|
|
CRowsetChange RowsetA;
|
|
CRowObject RowObjectA;
|
|
TESTC_(RowsetA.CreateRowset(),S_OK);
|
|
|
|
//Obtain row object
|
|
TESTC_(RowsetA.GetNextRows(&hRow),S_OK);
|
|
TEST2C_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow),S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
|
|
//Create ColAccess structures from the Rowset bindings
|
|
TESTC_(hr = RowObjectA.BindingsToColAccess(RowsetA.m_cBindings, RowsetA.m_rgBinding, RowsetA.m_pData, &cColAccess, &rgColAccess),S_OK);
|
|
|
|
//Verify SetColumns
|
|
TESTC(VerifySetColumns(&RowObjectA, FIRST_ROW, cColAccess, rgColAccess));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
FreeColAccess(cColAccess, rgColAccess);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - Asking for just Extra Row Columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_8()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
DBORDINAL cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
void* pData = NULL;
|
|
HROW hRow = NULL;
|
|
|
|
DBORDINAL cColumns = 0;
|
|
DBORDINAL* rgColOrdinals = NULL;
|
|
|
|
CRowsetChange RowsetA;
|
|
CRowObject RowObjectA;
|
|
TESTC_(RowsetA.CreateRowset(),S_OK);
|
|
|
|
//Obtain row object
|
|
TESTC_(RowsetA.GetNextRows(&hRow),S_OK);
|
|
TEST2C_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow),S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
|
|
//Obtain the just the Extra columns
|
|
TESTC_(hr = RowObjectA.GetExtraColumnInfo(&cColumns, NULL, NULL, &rgColOrdinals),S_OK);
|
|
|
|
//Create the ColAccess Structures for just the extra columns...
|
|
//Including BLOB columns bound as objects...
|
|
TESTC_(hr = RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, USE_COLS_TO_BIND_ARRAY | UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_COLS_BOUND, FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, cColumns, rgColOrdinals),S_OK);
|
|
|
|
//Verify SetColumns
|
|
TESTC(VerifySetColumns(&RowObjectA, FIRST_ROW, cColAccess, rgColAccess));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
FreeColAccess(cColAccess, rgColAccess);
|
|
SAFE_FREE(pData);
|
|
SAFE_FREE(rgColOrdinals);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - IUnknown Columns - native
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_9()
|
|
{
|
|
TBEGIN
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(this, BLOB_COLS_BOUND, BLOB_IID_IUNKNOWN));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_10()
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - Not Binding Value for all columns, pData is NULL - DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_11()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
void* pData = NULL;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
//NOTE: We are not bindings any BLOB columns, since this maybe allowed is pass a length
|
|
//only accessor for SetData on providers that need this info for BLOBs (this is covered seperatly...)
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL,
|
|
ECOLS_BOUND(UPDATEABLE_NONINDEX_COLS_BOUND | NONNULLABLE_COLS_BOUND), NO_BLOB_COLS,
|
|
FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, 0, NULL, DBPART_LENGTH|DBPART_STATUS),S_OK);
|
|
|
|
//FillColAccess
|
|
//NOTE: We bound only the non-nullable columns, so we don't have to worry about
|
|
//DBSTATUS_S_ISNULL passing, since value is not looked at...
|
|
TESTC_(m_pCRowObject->FillColAccess(pTable(), cColAccess, rgColAccess, SECOND_ROW),S_OK);
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->SetColumns(cColAccess, rgColAccess), cColAccess ? DB_E_ERRORSOCCURRED : S_OK);
|
|
|
|
//Verify Status'
|
|
//Length only bindings for SetData/SetColumns are not allowed, (only for BLOBs)
|
|
for(i=0; i<cColAccess; i++)
|
|
TESTC(rgColAccess[i].dwStatus == DBSTATUS_E_UNAVAILABLE);
|
|
|
|
FreeColAccess(cColAccess, rgColAccess);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - Not Binding Value for some columns, pData is NULL - DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_12()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
void* pData = NULL;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
//NOTE: We are not bindings any BLOB columns, since this maybe allowed is pass a length
|
|
//only accessor for SetData on providers that need this info for BLOBs (this is covered seperatly...)
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL,
|
|
ECOLS_BOUND(UPDATEABLE_NONINDEX_COLS_BOUND | NONNULLABLE_COLS_BOUND), NO_BLOB_COLS),S_OK);
|
|
|
|
//FillColAccess
|
|
//NOTE: We bound only the non-nullable columns, so we don't have to worry about
|
|
//DBSTATUS_S_ISNULL passing, since value is not looked at...
|
|
TESTC_(m_pCRowObject->FillColAccess(pTable(), cColAccess, rgColAccess, SECOND_ROW),S_OK);
|
|
|
|
//For some columns, don't bind the value
|
|
for(i=0; i<cColAccess; i++)
|
|
{
|
|
//Don't bind value for every other column...
|
|
//NOTE: We have one allocated pData that all the structures point into, so there
|
|
//is nothing to free, we just set this pointer to NULL...
|
|
if(i%2)
|
|
rgColAccess[i].pData = NULL;
|
|
}
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->SetColumns(cColAccess, rgColAccess), cColAccess>1 ? DB_S_ERRORSOCCURRED : S_OK);
|
|
|
|
//Make sure on output, that our pData's are unchanged!
|
|
for(i=0; i<cColAccess; i++)
|
|
{
|
|
if(i%2)
|
|
{
|
|
TESTC(rgColAccess[i].pData == NULL);
|
|
TESTC(rgColAccess[i].dwStatus == DBSTATUS_E_UNAVAILABLE);
|
|
}
|
|
else
|
|
{
|
|
//NOTE: Some providers maybe a "all-or-nothing" provider. So if one
|
|
//column was unable to be set they all contain UNAVAILABLE...
|
|
TESTC(rgColAccess[i].pData != NULL);
|
|
TESTC(rgColAccess[i].dwStatus == DBSTATUS_S_OK || rgColAccess[i].dwStatus == DBSTATUS_E_UNAVAILABLE);
|
|
}
|
|
}
|
|
|
|
FreeColAccess(cColAccess, rgColAccess);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - Not Binding Value for ISNULL columns, pData is NULL - S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_13()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
void* pData = NULL;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
//NOTE: Only bind the LENGTH and STATUS, and only bind the NULLABLE columns.
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL,
|
|
ECOLS_BOUND(UPDATEABLE_NONINDEX_COLS_BOUND | NULLABLE_COLS_BOUND), NO_BLOB_COLS,
|
|
FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, 0, NULL, DBPART_LENGTH|DBPART_STATUS),S_OK);
|
|
|
|
//FillColAccess
|
|
TESTC_(m_pCRowObject->FillColAccess(pTable(), cColAccess, rgColAccess, SECOND_ROW),S_OK);
|
|
|
|
//Bind all columns as ISNULL (so the value is ignored)
|
|
for(i=0; i<cColAccess; i++)
|
|
{
|
|
rgColAccess[i].dwStatus = DBSTATUS_S_ISNULL;
|
|
rgColAccess[i].pData = NULL;
|
|
}
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->SetColumns(cColAccess, rgColAccess), S_OK);
|
|
|
|
//Verify all the columns (come back as ISNULL)
|
|
TESTC_(m_pCRowObject->GetColumns(cColAccess, rgColAccess), S_OK);
|
|
for(i=0; i<cColAccess; i++)
|
|
TESTC(rgColAccess[i].dwStatus == DBSTATUS_S_ISNULL);
|
|
|
|
FreeColAccess(cColAccess, rgColAccess);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - Not Binding Value for BLOB columns, pData is NULL - S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_14()
|
|
{
|
|
TBEGIN
|
|
|
|
//Use a new rowset, and ask for a non-forward-only cursor, so we can obtain the data multiple times.
|
|
CRowsetChange RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_ACCESSORDER, DBPROPSET_ROWSET, (void*)DBPROPVAL_AO_RANDOM, DBTYPE_I4);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
//Only bind the LENGTH and STATUS for BLOB columns. This should succeed as this is the only
|
|
//allowed senario where SetData is allowed without the value bound...
|
|
TESTC(VerifySetColumnsAllRows(&RowsetA, BLOB_COLS_BOUND, BLOB_LONG, FORWARD,
|
|
NO_COLS_BY_REF, DBTYPE_EMPTY, 0, NULL, DBPART_LENGTH | DBPART_STATUS));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc SetColumns - Binding all columns, even read-only columns - DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_15()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
void* pData = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Before we do anything set the data to be the first row's data.
|
|
//So later when we change it to the second row we know it changed or didn't change
|
|
TESTC(m_pCRowObject->VerifySetColumns(FIRST_ROW, pTable()));
|
|
|
|
//Create the ColAccess Structures (for all columns - except index)...
|
|
//NOTE: This includes any potentially readonly, or other non-updateable columns
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, ECOLS_BOUND(NONINDEX_COLS_BOUND | NOBOOKMARK_COLS_BOUND)),S_OK);
|
|
|
|
//FillColAccess
|
|
//NOTE: We have to tell FillInputBindings to actually binding the readonly columns
|
|
//since it normally just puts IGNORE in those places...
|
|
TESTC_(m_pCRowObject->FillColAccess(pTable(), cColAccess, rgColAccess, SECOND_ROW, PRIMARY, NONINDEX_COLS_BOUND),S_OK);
|
|
|
|
//IRowChange::SetColumns
|
|
//NOTE: our helper verifies the hr to the status consensus...
|
|
TEST3C_(hr = m_pCRowObject->SetColumns(cColAccess, rgColAccess), S_OK, DB_S_ERRORSOCCURRED, DB_E_ERRORSOCCURRED);
|
|
|
|
//Verify all the columns
|
|
for(i=0; i<cColAccess; i++)
|
|
{
|
|
DBCOLUMNACCESS* pColAccess = &rgColAccess[i];
|
|
|
|
//First obtain the ColumnInfo for this column for greater verfication
|
|
DBCOLUMNINFO dbColInfo;
|
|
TESTC(::FindColInfo(m_pCRowObject->pIRow(), &pColAccess->columnid, 0, &dbColInfo, NULL));
|
|
|
|
//Now verify the data and status
|
|
switch(pColAccess->dwStatus)
|
|
{
|
|
case DBSTATUS_S_OK:
|
|
case DBSTATUS_S_ISNULL:
|
|
//Verify the Data is CHANGED (should the the second row's data)
|
|
TESTC_(m_pCRowObject->GetColumns(1, pColAccess), S_OK);
|
|
TESTC(m_pCRowObject->CompareColAccess(1, pColAccess, SECOND_ROW, pTable()));
|
|
|
|
//Make sure the column was updateable
|
|
TESTC(dbColInfo.dwFlags & DBCOLUMNFLAGS_WRITE || dbColInfo.dwFlags & DBCOLUMNFLAGS_WRITEUNKNOWN);
|
|
break;
|
|
|
|
default:
|
|
//Save the status before overwritting it with GetColumns
|
|
DBSTATUS dbSetColumnsStatus = pColAccess->dwStatus;
|
|
|
|
//Otherwise verify the data is UNCHANGED (should the the first row's data)
|
|
TESTC_(m_pCRowObject->GetColumns(1, pColAccess), S_OK);
|
|
if(dbColInfo.dwFlags & (DBCOLUMNFLAGS_ISROWID|DBCOLUMNFLAGS_ISROWVER))
|
|
{
|
|
//For RowIDs we can't compare against original value since its altered on
|
|
//on every setdata...
|
|
}
|
|
else
|
|
{
|
|
//Otherwise verify the data is UNCHANGED (should the the first row's data)
|
|
if(!m_pCRowObject->CompareColAccess(1, pColAccess, FIRST_ROW, pTable()))
|
|
TERROR("Data was incorrect for column (" << i << ")");
|
|
}
|
|
|
|
if(dbSetColumnsStatus == DBSTATUS_E_PERMISSIONDENIED)
|
|
TESTC(!(dbColInfo.dwFlags & DBCOLUMNFLAGS_WRITE || dbColInfo.dwFlags & DBCOLUMNFLAGS_WRITEUNKNOWN));
|
|
|
|
//The only error we should be expecting for this senario is PERMISSIONDENIED.
|
|
//We don't have a seperate case, since if some other error is returned for some
|
|
//reason (a bug) its more important that the data is not updated (first) then
|
|
//verification of the status takes second place...
|
|
TESTC(dbSetColumnsStatus == DBSTATUS_E_PERMISSIONDENIED ||
|
|
dbSetColumnsStatus == DBSTATUS_E_UNAVAILABLE);
|
|
break;
|
|
};
|
|
}
|
|
|
|
FreeColAccess(cColAccess, rgColAccess);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_16()
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Some valid, some non-existent columns - DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_17()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
DBORDINAL cColAccess2 = 0;
|
|
DBCOLUMNACCESS* rgColAccess2 = NULL;
|
|
void* pData = NULL;
|
|
void* pData2 = NULL;
|
|
DBORDINAL cColInvalid = 0;
|
|
DBCOLUMNACCESS* rgColInvalid = NULL;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
//NOTE: We do this twice, since we want to test invalid columnid within valid ids.
|
|
//A memcpy is not sufficient, since ColAccess contains ColIds which have to be allocated,
|
|
//as well as memory location buffers, etc. Easier to just call twice...
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG),S_OK);
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColAccess2, &rgColAccess2, &pData2, NULL, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG),S_OK);
|
|
|
|
//Now create complete ColAccess array, containing:
|
|
//Format = 1 Invalid, All Valid, 2 Invalid, All Valid, 1 Invalid
|
|
cColInvalid = 1 + cColAccess + 2 + cColAccess2 + 1;
|
|
SAFE_ALLOC(rgColInvalid, DBCOLUMNACCESS, cColInvalid);
|
|
//Create "Invalid" ColIDs
|
|
memset(rgColInvalid, 0, (size_t)(sizeof(DBCOLUMNACCESS) * cColInvalid));
|
|
//Create First set of All Valid
|
|
memcpy(&rgColInvalid[1], rgColAccess, (size_t)(sizeof(DBCOLUMNACCESS)*cColAccess));
|
|
//Create Second set of All Valid
|
|
memcpy(&rgColInvalid[1 + cColAccess + 2], rgColAccess2, (size_t)(sizeof(DBCOLUMNACCESS)*cColAccess2));
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->FillColAccess(pTable(), cColAccess, &rgColInvalid[1], SECOND_ROW),S_OK);
|
|
TESTC_(m_pCRowObject->FillColAccess(pTable(), cColAccess2, &rgColInvalid[1 + cColAccess + 2], SECOND_ROW),S_OK);
|
|
TESTC_(m_pCRowObject->SetColumns(cColInvalid, rgColInvalid),DB_S_ERRORSOCCURRED);
|
|
|
|
//Verify Status'
|
|
TESTC(rgColInvalid[0].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
TESTC(rgColInvalid[1 + cColAccess + 0].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
TESTC(rgColInvalid[1 + cColAccess + 1].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
TESTC(rgColInvalid[1 + cColAccess + 2 + cColAccess2].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
|
|
//Compare First All Valid Columns
|
|
TESTC_(m_pCRowObject->GetColumns(cColAccess, &rgColInvalid[1]),S_OK);
|
|
TESTC(m_pCRowObject->CompareColAccess(cColAccess, &rgColInvalid[1], SECOND_ROW, pTable()));
|
|
|
|
//Compare Second All Valid Columns
|
|
TESTC_(m_pCRowObject->GetColumns(cColAccess2, &rgColInvalid[1 + cColAccess + 2]),S_OK);
|
|
TESTC(m_pCRowObject->CompareColAccess(cColAccess2, &rgColInvalid[1 + cColAccess + 2], SECOND_ROW, pTable()));
|
|
|
|
FreeColAccess(cColAccess, rgColAccess);
|
|
FreeColAccess(cColAccess2, rgColAccess2);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
SAFE_FREE(pData2);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - All non-existent columns - DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_18()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColInvalid = 0;
|
|
DBCOLUMNACCESS* rgColInvalid = NULL;
|
|
void* pData = NULL;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColInvalid, &rgColInvalid, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG),S_OK);
|
|
|
|
//Now replace the Array with (unique/nonexistent) columns
|
|
for(i=0; i<cColInvalid; i++)
|
|
{
|
|
//Create a unique ColID name
|
|
TESTC_(CreateUniqueDBID(&rgColInvalid[i].columnid),S_OK);
|
|
}
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->SetColumns(cColInvalid, rgColInvalid),DB_E_ERRORSOCCURRED);
|
|
|
|
//Verify Status'
|
|
for(i=0; i<cColInvalid; i++)
|
|
TESTC(rgColInvalid[i].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
|
|
FreeColAccess(cColInvalid, rgColInvalid);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Vector Columns - S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_19()
|
|
{
|
|
TBEGIN
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(this, ECOLS_BOUND(NOVECTOR_COLS_BOUND | UPDATEABLE_NONINDEX_COLS_BOUND)));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Vectors and Non-Existent Columns - DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_20()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColInvalid = 0;
|
|
DBCOLUMNACCESS* rgColInvalid = NULL;
|
|
void* pData = NULL;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColInvalid, &rgColInvalid, &pData, NULL, NOVECTOR_COLS_BOUND, BLOB_LONG),S_OK);
|
|
|
|
//Now replace the Array with (unique/nonexistent) columns
|
|
for(i=0; i<cColInvalid; i++)
|
|
{
|
|
//Create a unique ColID name
|
|
TESTC_(CreateUniqueDBID(&rgColInvalid[i].columnid),S_OK);
|
|
}
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->SetColumns(cColInvalid, rgColInvalid),DB_E_ERRORSOCCURRED);
|
|
|
|
//Verify Status'
|
|
for(i=0; i<cColInvalid; i++)
|
|
TESTC(rgColInvalid[i].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
|
|
FreeColAccess(cColInvalid, rgColInvalid);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Only Vector Columns - S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_21()
|
|
{
|
|
TBEGIN
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(this, ECOLS_BOUND(VECTOR_COLS_BOUND | UPDATEABLE_NONINDEX_COLS_BOUND)));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Only Non-Existent Vector Columns - DB_E_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_22()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColInvalid = 0;
|
|
DBCOLUMNACCESS* rgColInvalid = NULL;
|
|
void* pData = NULL;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColInvalid, &rgColInvalid, &pData, NULL, VECTOR_COLS_BOUND),S_OK);
|
|
|
|
//Now replace the Array with (unique/nonexistent) columns
|
|
for(i=0; i<cColInvalid; i++)
|
|
{
|
|
//Create a unique ColID name
|
|
TESTC_(CreateUniqueDBID(&rgColInvalid[i].columnid),S_OK);
|
|
}
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->SetColumns(cColInvalid, rgColInvalid), cColInvalid ? DB_E_ERRORSOCCURRED : S_OK);
|
|
|
|
//Verify Status'
|
|
for(i=0; i<cColInvalid; i++)
|
|
TESTC(rgColInvalid[i].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
|
|
FreeColAccess(cColInvalid, rgColInvalid);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Valid Vectors and Non-Existent Columns - DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_23()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColInvalid = 0;
|
|
DBCOLUMNACCESS* rgColInvalid = NULL;
|
|
void* pData = NULL;
|
|
ULONG cNonVectors = 0;
|
|
HRESULT hrExpected = S_OK;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColInvalid, &rgColInvalid, &pData, NULL, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG),S_OK);
|
|
|
|
//Now for all non-vectors, create a new invalid colid
|
|
for(i=0; i<cColInvalid; i++)
|
|
{
|
|
//Create a unique ColID name (for all non-vectors)
|
|
if(rgColInvalid[i].wType & DBTYPE_VECTOR)
|
|
{
|
|
TESTC_(m_pCRowObject->FillColAccess(pTable(), 1, &rgColInvalid[i], THIRD_ROW),S_OK);
|
|
}
|
|
else
|
|
{
|
|
TESTC_(CreateUniqueDBID(&rgColInvalid[i].columnid),S_OK);
|
|
cNonVectors++;
|
|
}
|
|
}
|
|
|
|
if(cColInvalid)
|
|
hrExpected = (cColInvalid == cNonVectors) ? DB_E_ERRORSOCCURRED : DB_S_ERRORSOCCURRED;
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->SetColumns(cColInvalid, rgColInvalid), hrExpected);
|
|
|
|
//Verify Status'
|
|
for(i=0; i<cColInvalid; i++)
|
|
{
|
|
if(rgColInvalid[i].wType & DBTYPE_VECTOR)
|
|
{
|
|
TESTC(rgColInvalid[i].dwStatus == DBSTATUS_S_OK || rgColInvalid[i].dwStatus == DBSTATUS_S_ISNULL);
|
|
TESTC_(m_pCRowObject->GetColumns(1, &rgColInvalid[i]),S_OK);
|
|
TESTC(m_pCRowObject->CompareColAccess(1, &rgColInvalid[i], THIRD_ROW, pTable()));
|
|
}
|
|
else
|
|
{
|
|
//Only non-vectors where changed to non-existent columnids
|
|
TESTC(rgColInvalid[i].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
}
|
|
}
|
|
|
|
FreeColAccess(cColInvalid, rgColInvalid);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Valid Non-Vectors and Non-Existent Vector Columns - DB_S_ERRORSOCCURRED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_24()
|
|
{
|
|
TBEGIN
|
|
DBORDINAL i,cColInvalid = 0;
|
|
DBCOLUMNACCESS* rgColInvalid = NULL;
|
|
void* pData = NULL;
|
|
ULONG cVectors = 0;
|
|
HRESULT hrExpected = S_OK;
|
|
|
|
//Create the ColAccess Structures (for all columns)...
|
|
TESTC_(m_pCRowObject->CreateColAccess(&cColInvalid, &rgColInvalid, &pData, NULL, UPDATEABLE_NONINDEX_COLS_BOUND, NO_BLOB_COLS),S_OK);
|
|
|
|
//Now for all non-vectors, create a new invalid colid
|
|
for(i=0; i<cColInvalid; i++)
|
|
{
|
|
//Create a unique ColID name (for all non-vectors)
|
|
if(rgColInvalid[i].wType & DBTYPE_VECTOR)
|
|
{
|
|
TESTC_(CreateUniqueDBID(&rgColInvalid[i].columnid),S_OK);
|
|
cVectors++;
|
|
}
|
|
else
|
|
{
|
|
TESTC_(m_pCRowObject->FillColAccess(pTable(), 1, &rgColInvalid[i], THIRD_ROW),S_OK);
|
|
}
|
|
}
|
|
|
|
if(cColInvalid)
|
|
hrExpected = (cColInvalid == cVectors) ? DB_E_ERRORSOCCURRED : DB_S_ERRORSOCCURRED;
|
|
|
|
//IRowChange::SetColumns
|
|
TESTC_(m_pCRowObject->SetColumns(cColInvalid, rgColInvalid), hrExpected);
|
|
|
|
//Verify Status'
|
|
for(i=0; i<cColInvalid; i++)
|
|
{
|
|
if(rgColInvalid[i].wType & DBTYPE_VECTOR)
|
|
{
|
|
//Only vectors where changed to non-existent columnids
|
|
TESTC(rgColInvalid[i].dwStatus == DBSTATUS_E_DOESNOTEXIST);
|
|
}
|
|
else
|
|
{
|
|
TESTC(rgColInvalid[i].dwStatus == DBSTATUS_S_OK || rgColInvalid[i].dwStatus == DBSTATUS_S_ISNULL || rgColInvalid[i].dwStatus == DBSTATUS_S_IGNORE);
|
|
TESTC_(m_pCRowObject->GetColumns(1, &rgColInvalid[i]),S_OK);
|
|
TESTC(m_pCRowObject->CompareColAccess(1, &rgColInvalid[i], THIRD_ROW, pTable()));
|
|
}
|
|
}
|
|
|
|
FreeColAccess(cColInvalid, rgColInvalid);
|
|
|
|
CLEANUP:
|
|
SAFE_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_25()
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Status - DBSTATUS_S_ISNULL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_26()
|
|
{
|
|
TBEGIN
|
|
|
|
//ISNULL is tested basically for free. The privlib table, will contain a NULL diagonal,
|
|
//or if using the INI file, somewhere within the file its pretty likely there is a NULL
|
|
//value somewhere. This way we can just loop through all rows in the table and insert data
|
|
//for that row to test SetColumns with a NULL value.
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(this, UPDATEABLE_NONINDEX_COLS_BOUND));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Status - DBSTATUS_S_DEFAULT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_27()
|
|
{
|
|
//NOTE: This senario is already tested in the IRowsetChange test against
|
|
//a provider that supports Row Objects it uses SetColumns under the covers so we don't
|
|
//have to reinvent every new variation senario.
|
|
|
|
//We could duplicate the senario just for completeness, but with the current time
|
|
//constraints and the complexity of the verification we'll not duplciate efforts
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Status - DBSTATUS_S_IGNORE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_28()
|
|
{
|
|
//NOTE: This senario is already tested in the IRowsetChange test against
|
|
//a provider that supports Row Objects it uses SetColumns under the covers so we don't
|
|
//have to reinvent every new variation senario.
|
|
|
|
//We could duplicate the senario just for completeness, but with the current time
|
|
//constraints and the complexity of the verification we'll not duplciate efforts
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_29()
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Buffered Mode - All Columns - no BLOBs
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_30()
|
|
{
|
|
TBEGIN
|
|
|
|
//Create a buffered mode rowset
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//Not all providers will support IRowsetUpdate
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(&RowsetA, UPDATEABLE_NONINDEX_COLS_BOUND));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Buffered Mode - All Columns - BLOBs
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_31()
|
|
{
|
|
TBEGIN
|
|
|
|
//Create a buffered mode rowset
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//Not all providers will support IRowsetUpdate
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Loop through all the rows in the rowset, verify the columns...
|
|
TESTC(VerifySetColumnsAllRows(&RowsetA, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Buffered Mode - All Columns - Just extra columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_32()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
DBORDINAL cColAccess = 0;
|
|
DBCOLUMNACCESS* rgColAccess = NULL;
|
|
void* pData = NULL;
|
|
|
|
DBORDINAL cColumns = 0;
|
|
DBORDINAL* rgColOrdinals = NULL;
|
|
HROW hRow = NULL;
|
|
|
|
//Create a buffered mode rowset
|
|
CRowsetUpdate RowsetA;
|
|
CRowObject RowObjectA;
|
|
|
|
//Not all providers will support IRowsetUpdate
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the First row...
|
|
TESTC_(RowsetA.GetNextRows(&hRow),S_OK);
|
|
|
|
//Now create the row object.
|
|
TEST2C_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow), S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
|
|
//Obtain the just the Extra columns
|
|
TESTC_(hr = RowObjectA.GetExtraColumnInfo(&cColumns, NULL, NULL, &rgColOrdinals),S_OK);
|
|
|
|
//Create the ColAccess Structures for just the extra columns...
|
|
TESTC_(hr = RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG, FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, cColumns, rgColOrdinals),S_OK);
|
|
|
|
//Verify SetColumns
|
|
TESTC(VerifySetColumns(&RowObjectA, FIRST_ROW, cColAccess, rgColAccess));
|
|
|
|
CLEANUP:
|
|
FreeColAccess(cColAccess, rgColAccess);
|
|
SAFE_FREE(pData);
|
|
SAFE_FREE(rgColOrdinals);
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_33()
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multiple Row Object - same row
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_34()
|
|
{
|
|
TBEGIN
|
|
HROW hRow = NULL;
|
|
CRowsetChange RowsetA;
|
|
CRowObject RowObjectA;
|
|
CRowObject RowObjectB;
|
|
|
|
//Create the rowset
|
|
TESTC_(RowsetA.CreateRowset(),S_OK);
|
|
|
|
//Obtain the First row...
|
|
TESTC_(RowsetA.GetNextRows(&hRow),S_OK);
|
|
|
|
//Now create the row object.
|
|
TEST2C_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow), S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
TESTC(VerifySetColumns(&RowObjectA, THIRD_ROW, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
|
|
//Now verify the data as seen from a new row object over the same row
|
|
TEST2C_(RowObjectB.CreateRowObject(RowsetA.pIRowset(), hRow), S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
TESTC(RowObjectB.VerifyGetColumns(THIRD_ROW, pTable(), UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multiple Row Object - different rows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_35()
|
|
{
|
|
TBEGIN
|
|
HROW rghRows[TWO_ROWS];
|
|
CRowsetChange RowsetA;
|
|
CRowObject RowObjectA;
|
|
CRowObject RowObjectB;
|
|
|
|
//Create the rowset
|
|
TESTC_(RowsetA.CreateRowset(),S_OK);
|
|
|
|
//Obtain the First row...
|
|
TESTC_(RowsetA.GetNextRows(TWO_ROWS, rghRows),S_OK);
|
|
|
|
//Now create the row objects.
|
|
TEST2C_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), rghRows[ROW_ONE]), S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
TEST2C_(RowObjectB.CreateRowObject(RowsetA.pIRowset(), rghRows[ROW_TWO]), S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
|
|
//Verify SetColumns (create and set data, using the third row data into this row)
|
|
TESTC(VerifySetColumns(&RowObjectA, THIRD_ROW, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
TESTC(VerifySetColumns(&RowObjectB, FOURTH_ROW, UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
|
|
//Now verify the data as seen from a new row object over the same row
|
|
TESTC(RowObjectB.VerifyGetColumns(FOURTH_ROW, pTable(), UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
TESTC(RowObjectA.VerifyGetColumns(THIRD_ROW, pTable(), UPDATEABLE_NONINDEX_COLS_BOUND, BLOB_LONG));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(TWO_ROWS, rghRows);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_36()
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Threads - SetColumns seperate threads [same row object]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCIRowChange_SetColumns::Variation_37()
|
|
{
|
|
TBEGIN
|
|
INIT_THREADS(MAX_THREADS);
|
|
|
|
CRowsetChange RowsetA;
|
|
CRowObject RowObjectA;
|
|
HROW hRow = NULL;
|
|
|
|
//Setup Thread Arguments
|
|
THREADARG T1Arg = { this, &RowObjectA };
|
|
|
|
//Create Rowset object
|
|
RowsetA.SetSettableProperty(DBPROP_IRowsetLocate);
|
|
RowsetA.SetProperty(DBPROP_CANHOLDROWS);
|
|
TESTC_(RowsetA.CreateRowset(),S_OK);
|
|
|
|
//Obtain row object
|
|
TESTC_(RowsetA.GetNextRows(&hRow),S_OK);
|
|
TEST2C_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow),S_OK, DB_S_NOROWSPECIFICCOLUMNS);
|
|
|
|
//Create Threads
|
|
CREATE_THREADS(Thread_VerifySetColumns, &T1Arg);
|
|
|
|
START_THREADS();
|
|
END_THREADS();
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCIRowChange_SetColumns::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(TCIRowChange::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCTransactions)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCTransactions - IRowChange inside Transactions
|
|
//| Created: 8/5/98
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCTransactions::Init()
|
|
{
|
|
if(CTransaction::Init())
|
|
{
|
|
//register interface to be tested
|
|
if(RegisterInterface(ROWSET_INTERFACE, IID_IGetRow, 0, NULL))
|
|
return TRUE;
|
|
}
|
|
|
|
//Not all providers have to support transactions
|
|
//If a required interface, an error would have 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 TCTransactions::Variation_1()
|
|
{
|
|
return VerifyTransaction(FALSE/*fCommit*/, TRUE/*fRetaining*/);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc ABORT with fRetaining FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCTransactions::Variation_2()
|
|
{
|
|
return VerifyTransaction(FALSE/*fCommit*/, FALSE/*fRetaining*/);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc COMMIT with fRetaining TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCTransactions::Variation_3()
|
|
{
|
|
return VerifyTransaction(TRUE/*fCommit*/, TRUE/*fRetaining*/);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc COMMIT with fRetaining FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCTransactions::Variation_4()
|
|
{
|
|
return VerifyTransaction(TRUE/*fCommit*/, FALSE/*fRetaining*/);
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCTransactions::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTransaction::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|
|
|