//-------------------------------------------------------------------- // Microsoft OLE DB Test // // Copyright (C) 1995-2000 Microsoft Corporation // // @doc // // @module IRow.cpp | This module tests the OLEDB IRow interface // #include "MODStandard.hpp" // Standard headers #include "IRow.h" // IRow header #include "ExtraLib.h" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Module Values // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // {{ TCW_MODULE_GLOBALS DECLARE_MODULE_CLSID = { 0xf61ea340, 0x2b1e, 0x11d2, { 0xa9, 0x8d, 0x00, 0xc0, 0x4f, 0x94, 0xa7, 0x17} }; DECLARE_MODULE_NAME("IRow"); DECLARE_MODULE_OWNER("Microsoft"); DECLARE_MODULE_DESCRIP("IRow 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 //NOTE: I need at least as many rows as columns so cover the case of the BLOB columns being NULL... if(GetInterfaceArray(ROW_INTERFACE, &cInterfaceIIDs, &rgInterfaceIIDs)) return CommonModuleInit(pThisTestModule, IID_IRow, max(25,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); } //////////////////////////////////////////////////////////////////////////// // TCIRow // //////////////////////////////////////////////////////////////////////////// class TCIRow : public CRowset { public: //constructors TCIRow(WCHAR* pwszTestCaseName = INVALID(WCHAR*)); virtual ~TCIRow(); //methods virtual BOOL Init(); virtual BOOL Terminate(); //IRow virtual BOOL VerifyGetColumns ( CRowObject* pCRowObject, DBCOUNTITEM iRow, ECOLS_BOUND eColsToBind = ALL_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_LENGTH|DBPART_STATUS ); virtual BOOL VerifyGetColumnsAllRows ( CRowset* pCRowset, ECOLS_BOUND eColsToBind = ALL_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_LENGTH|DBPART_STATUS ); virtual BOOL VerifyGetSourceRowset ( REFIID riid, IUnknown** ppIRowset = NULL, HROW* phRow = NULL ); virtual HRESULT FindObject ( CRowObject* pCRowObject, IUnknown* pUnkOuter, REFGUID rguid, REFIID riid, IUnknown** ppIUnknown, DBID** ppColumnID ); virtual BOOL VerifyOpenAllColumns ( IUnknown* pIUnkOuter, CRowObject* pCRowObject, DBCOUNTITEM iRow, REFGUID rGuidType, REFIID riid = IID_IUnknown, ECOLS_BOUND eColsToBind = ALL_COLS_BOUND, BLOBTYPE dwBlobType = BLOB_LONG, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE dwModifier = DBTYPE_EMPTY, DBORDINAL cColsToBind = 0, DBORDINAL* rgColsToBind = NULL ); virtual BOOL VerifyOpenAllRows ( CRowset* pCRowset, REFGUID rGuidType, REFIID riid = IID_IUnknown, ECOLS_BOUND eColsToBind = ALL_COLS_BOUND, BLOBTYPE dwBlobType = BLOB_LONG, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE dwModifier = DBTYPE_EMPTY, DBORDINAL cColsToBind = 0, DBORDINAL* rgColsToBind = NULL ); virtual BOOL VerifyOpenAllInterfaces ( EINTERFACE eInterface, REFGUID rGuidType ); virtual BOOL VerifyOpenWithOpenObjects ( REFGUID rGuidtype, REFIID riid ); virtual BOOL VerifyOpenWithOpenObjects ( REFGUID rGuidtype, REFIID riid, CRowObject *pRowObjects, DWORD *pThreadIDs, bool fDifferentColumns ); //Thread Methods static ULONG WINAPI Thread_VerifyGetColumns(LPVOID pv); static ULONG WINAPI Thread_VerifyGetSourceRowset(LPVOID pv); static ULONG WINAPI Thread_VerifyOpenWithOpenObjects(LPVOID pv); //Interface //Data CRowObject* m_pCRowObject; }; //////////////////////////////////////////////////////////////////////////// // TCIRow::TCIRow // //////////////////////////////////////////////////////////////////////////// TCIRow::TCIRow(WCHAR * wstrTestCaseName) : CRowset(wstrTestCaseName) { m_pCRowObject = NULL; } //////////////////////////////////////////////////////////////////////////// // TCIRow::~TCIRow // //////////////////////////////////////////////////////////////////////////// TCIRow::~TCIRow() { } //////////////////////////////////////////////////////////////////////////// // TCIRow::Init // //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::Init() { TBEGIN HRESULT hr = S_OK; //Create the new row object m_pCRowObject = new CRowObject; TESTC(m_pCRowObject != NULL); TESTC(CRowset::Init()); //May require AccessOrder to position on Blobs // SetSettableProperty(DBPROP_IRowsetLocate, DBPROPSET_ROWSET, (void*)VARIANT_TRUE, DBTYPE_BOOL); SetSettableProperty(DBPROP_ACCESSORDER, DBPROPSET_ROWSET, (void*)DBPROPVAL_AO_RANDOM, DBTYPE_I4); //CANHOLDROWS is a required property //We need this since we create 1 rowset, but each variation obtains rows from different positions //many times restarting to obtain a previous row... SetProperty(DBPROP_CANHOLDROWS); //Create the Rowset object TESTC_(CreateRowset(SELECT_ORDERBYNUMERIC), S_OK); //Obtain the first row object TESTC_(GetRowObject(FIRST_ROW, m_pCRowObject),S_OK); CLEANUP: TRETURN } //////////////////////////////////////////////////////////////////////////// // TCIRow::Terminate // //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::Terminate() { SAFE_DELETE(m_pCRowObject); return CRowset::Terminate(); } //////////////////////////////////////////////////////////////////////////// // TCIRow::VerifyGetColumns // //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::VerifyGetColumns ( CRowObject* pCRowObject, DBCOUNTITEM iRow, ECOLS_BOUND eColsToBind, BLOBTYPE dwBlobType, ECOLUMNORDER eBindingOrder, ECOLS_BY_REF eColsByRef, DBTYPE dwModifier, DBORDINAL cColsToBind, DBORDINAL* rgColsToBind, DBPART dwPart ) { //Delegate return pCRowObject->VerifyGetColumns(iRow, pTable(), eColsToBind, dwBlobType, eBindingOrder, eColsByRef, dwModifier, cColsToBind, rgColsToBind, dwPart); } //////////////////////////////////////////////////////////////////////////// // TCIRow::VerifyGetColumnsAllRows // //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::VerifyGetColumnsAllRows ( CRowset* 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 hRow = NULL; CRowset RowsetA; //Default rowset if(pCRowset == NULL) { pCRowset = &RowsetA; //May require AccessOrder to position on Blobs if(dwBlobType != NO_BLOB_COLS) pCRowset->SetSettableProperty(DBPROP_ACCESSORDER, DBPROPSET_ROWSET, (void*)DBPROPVAL_AO_RANDOM, DBTYPE_I4); TESTC_(pCRowset->CreateRowset(),S_OK); } //Restart the position. TESTC_(pCRowset->RestartPosition(),S_OK); //loop through the rowset, retrieve one row at a time for(iRow=1; iRow<=pCRowset->m_ulTableRows; iRow++) { //GetNextRow CRowObject RowObjectA; TESTC_(pCRowset->GetNextRows(&hRow),S_OK); //Create the row object from this row TESTC_(pCRowset->GetRowObject(iRow, &RowObjectA, 0, hRow), S_OK); //Verify Row Object if(!VerifyGetColumns(&RowObjectA, iRow, eColsToBind, dwBlobType, eBindingOrder, eColsByRef, dwModifier, cColsToBind, rgColsToBind, dwPart)) { //Data incorrect for this row! TERROR("Data was incorrect for row " << iRow); QTESTC(FALSE); } //release the row handle TESTC_(pCRowset->ReleaseRows(hRow),S_OK); } CLEANUP: RowsetA.ReleaseRows(hRow); TRETURN } /////////////////////////////////////////////////////////////////////////// // TCIRow::VerifyGetSourceRowset // //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::VerifyGetSourceRowset ( REFIID riid, IUnknown** ppIRowset, HROW* phRow ) { TBEGIN HRESULT hr = S_OK; IUnknown* pIUnknown = NULL; HROW hRow = NULL; //IRow::GetSourceRowset... //NOTE: Verification is done in the helper TEST2C_(hr = m_pCRowObject->GetSourceRowset(riid, &pIUnknown, &hRow),S_OK,DB_E_NOSOURCEOBJECT); CLEANUP: if(ppIRowset) *ppIRowset = pIUnknown; else SAFE_RELEASE(pIUnknown); if(phRow) *phRow = hRow; else ReleaseRows(hRow); TRETURN } /////////////////////////////////////////////////////////////////////////// // TCIRow::VerifyOpenAllColumns // //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::VerifyOpenAllColumns ( IUnknown* pIUnkOuter, CRowObject* pCRowObject, DBCOUNTITEM iRow, REFGUID rGuidType, REFIID riid, ECOLS_BOUND eColsToBind, BLOBTYPE dwBlobType, ECOLUMNORDER eBindingOrder, ECOLS_BY_REF eColsByRef, DBTYPE dwModifier, DBORDINAL cColsToBind, DBORDINAL* rgColsToBind ) { TBEGIN ASSERT(pCRowObject); HRESULT hr = S_OK; DBORDINAL i,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),S_OK); //IRow::Open (for all bound columns) for(i=0; iVerifyOpen(iRow, pTable(), pIUnkOuter, &rgColAccess[i].columnid, rGuidType, riid); TEST4C_(hr, S_OK, DB_E_NOTFOUND, DB_E_OBJECTMISMATCH, E_NOINTERFACE); //Produce a error if this was an IUnknown column and it could not be opened... //At the very least a consumer should be able to open the column as the default //native object type (GUID_NULL, and IID_IUnknown) if(FAILED(hr)) { if(rgColAccess[i].wType==DBTYPE_IUNKNOWN && rGuidType == GUID_NULL && riid == IID_IUnknown) TOUTPUT("WARNING: IUnknown column unable to be opened with IRow::Open(GUID_NULL, IID_IUnknown...)?"); } } //DBROWCOL_DEFAULTSTREAM //Now that we have done the returned columns, lets also see if there is a default stream object. TEST4C_(hr = pCRowObject->Open(pIUnkOuter, &DBROWCOL_DEFAULTSTREAM, DBGUID_STREAM, IID_IStream), S_OK, DB_E_NOTFOUND, DB_E_BADCOLUMNID, DB_E_NOAGGREGATION); //Only Allow no aggregation if using a controlling unknown if(hr == DB_E_NOAGGREGATION) TESTC(pIUnkOuter != NULL); CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(pData); TRETURN } //////////////////////////////////////////////////////////////////////////// // TCIRow::VerifyOpenAllRows // //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::VerifyOpenAllRows ( CRowset* pCRowset, REFGUID rGuidType, REFIID riid, ECOLS_BOUND eColsToBind, BLOBTYPE dwBlobType, ECOLUMNORDER eBindingOrder, ECOLS_BY_REF eColsByRef, DBTYPE dwModifier, DBORDINAL cColsToBind, DBORDINAL* rgColsToBind ) { TBEGIN HRESULT hr = S_OK; CRowset RowsetA; HROW hRow = NULL; DBCOUNTITEM iRow = 0; //Default rowset if(pCRowset == NULL) { pCRowset = &RowsetA; TESTC_(pCRowset->CreateRowset(),S_OK); } //loop through the rowset, retrieve one row at a time for(iRow=1; iRow<=pCRowset->m_ulTableRows; iRow++) { //GetNextRow CRowObject RowObjectA; TESTC_(pCRowset->GetNextRows(&hRow),S_OK); //Create the row object from this row TESTC_(pCRowset->GetRowObject(iRow, &RowObjectA, 0, hRow),S_OK); //Verify Row Object TESTC(VerifyOpenAllColumns(NULL, &RowObjectA, iRow, rGuidType, riid, eColsToBind, dwBlobType, eBindingOrder, eColsByRef, dwModifier, cColsToBind, rgColsToBind)); //release the row handle TESTC_(pCRowset->ReleaseRows(hRow),S_OK); } CLEANUP: pCRowset->ReleaseRows(hRow); TRETURN } //////////////////////////////////////////////////////////////////////////// // TCIRow::VerifyOpenAllInterfaces // //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::VerifyOpenAllInterfaces(EINTERFACE eInterface, REFGUID rGuidType) { TBEGIN HRESULT hr = S_OK; //Obtain the Rowset interfaces... ULONG iCol,cIIDs = 0; INTERFACEMAP* rgIIDs = NULL; GetInterfaceArray(eInterface, &cIIDs, &rgIIDs); //Obtain the row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Loop through all the columns... for(iCol=0; iColcolumnid; //Open the column as a stream object (and keep it open) HRESULT hr = RowObjectA.VerifyOpen(FIRST_ROW, pTable(), NULL, pColumnID, rGuidType, riid, &pIUnknown); TEST4C_(hr, S_OK, DB_E_NOTFOUND, DB_E_OBJECTMISMATCH, E_NOINTERFACE); if(hr==S_OK) { if(rGuidType == DBGUID_STREAM) { //The helper already read and verified the stream... } else if(rGuidType == DBGUID_ROW) { //GetSourceRowset ASSERT(riid == IID_IRow); TEST2C_(((IRow*)pIUnknown)->GetSourceRowset(IID_IRowset, &pIRowset, NULL),S_OK,DB_E_NOSOURCEOBJECT); } //Try Opening the Object again hr = RowObjectA.VerifyOpen(FIRST_ROW, pTable(), NULL, pColumnID, rGuidType, riid, &pIUnknown2); TEST5C_(hr, S_OK, DB_E_NOTFOUND, DB_E_OBJECTMISMATCH, DB_E_OBJECTOPEN, E_NOINTERFACE); if(hr==S_OK) { if(rGuidType == DBGUID_STREAM) { //The helper already read and verified the stream... } else if(rGuidType == DBGUID_ROW) { //GetSourceRowset ASSERT(riid == IID_IRow); TEST2C_(((IRow*)pIUnknown)->GetSourceRowset(IID_IRowset, &pIRowset2, NULL),S_OK,DB_E_NOSOURCEOBJECT); if(pIRowset && pIRowset2) TESTC(VerifyEqualInterface(pIRowset, pIRowset2)); } } } if(FAILED(hr) && hr!=DB_E_OBJECTOPEN) { //Produce a error if this was an IUnknown column and it could not be opened... //At the very least a consumer should be able to open the column as the default //native object type (GUID_NULL, and IID_IUnknown) if(pColAccess->wType==DBTYPE_IUNKNOWN && rGuidType == GUID_NULL && riid == IID_IUnknown) TOUTPUT("WARNING: IUnknown column unable to be opened with IRow::Open(GUID_NULL, IID_IUnknown...)?"); } //Release all Objects SAFE_RELEASE(pIUnknown); SAFE_RELEASE(pIUnknown2); SAFE_RELEASE(pIRowset); SAFE_RELEASE(pIRowset2); } CLEANUP: //Release all Objects SAFE_RELEASE(pIUnknown); SAFE_RELEASE(pIUnknown2); SAFE_RELEASE(pIRowset); SAFE_RELEASE(pIRowset2); TRETURN } //////////////////////////////////////////////////////////////////////////// // Version of TCIRow::VerifyOpenWithOpenObjects with minimized privlib // code usage, to avoid multithreading issues //////////////////////////////////////////////////////////////////////////// BOOL TCIRow::VerifyOpenWithOpenObjects( REFGUID rGuidType, REFIID riid, CRowObject *pRowObjects, DWORD *pThreadIDs, bool fDifferentColumns) { TBEGIN IUnknown* pIUnknown = NULL; IUnknown* pIUnknown2 = NULL; IUnknown* pIRowset = NULL; IUnknown* pIRowset2 = NULL; ULONG iCol = 0; //lookup the row object DWORD dwCurrentThreadID = GetCurrentThreadId(); CRowObject *pRowObject; for (int i = 0; ; ++i) { if (pThreadIDs[i] == dwCurrentThreadID) { pRowObject = pRowObjects + i; break; } } //Loop through all the columns... for(iCol=0; iColm_cColAccess; iCol++) { DBCOLUMNACCESS* pColAccess = &pRowObject->m_rgColAccess[iCol]; //need only columnid and wType DBID* pColumnID = &pColAccess->columnid; // do several iterations over same column for (DBORDINAL iteration = 0; iteration < 10; ++iteration) { //Open the column as a stream object (and keep it open) HRESULT hr = pRowObject->VerifyOpen(FIRST_ROW, pTable(), NULL, pColumnID, rGuidType, riid, &pIUnknown); //Depending upon thread timing we may encounter an open object TEST5C_(hr, S_OK, DB_E_NOTFOUND, DB_E_OBJECTMISMATCH, E_NOINTERFACE,DB_E_OBJECTOPEN); if(hr==S_OK) { if(rGuidType == DBGUID_STREAM) { //The helper already read and verified the stream... } else if(rGuidType == DBGUID_ROW) { //GetSourceRowset ASSERT(riid == IID_IRow); TEST2C_(((IRow*)pIUnknown)->GetSourceRowset(IID_IRowset, &pIRowset, NULL),S_OK,DB_E_NOSOURCEOBJECT); } //Try Opening the Object again hr = pRowObject->VerifyOpen(FIRST_ROW, pTable(), NULL, pColumnID, rGuidType, riid, &pIUnknown2); TEST5C_(hr, S_OK, DB_E_NOTFOUND, DB_E_OBJECTMISMATCH, DB_E_OBJECTOPEN, E_NOINTERFACE); if(hr==S_OK) { if(rGuidType == DBGUID_STREAM) { //The helper already read and verified the stream... } else if(rGuidType == DBGUID_ROW) { //GetSourceRowset ASSERT(riid == IID_IRow); TEST2C_(((IRow*)pIUnknown)->GetSourceRowset(IID_IRowset, &pIRowset2, NULL),S_OK,DB_E_NOSOURCEOBJECT); if(pIRowset && pIRowset2) TESTC(VerifyEqualInterface(pIRowset, pIRowset2)); } } } if(FAILED(hr) && hr!=DB_E_OBJECTOPEN) { //Produce a error if this was an IUnknown column and it could not be opened... //At the very least a consumer should be able to open the column as the default //native object type (GUID_NULL, and IID_IUnknown) if(pColAccess->wType==DBTYPE_IUNKNOWN && rGuidType == GUID_NULL && riid == IID_IUnknown) TOUTPUT("WARNING: IUnknown column unable to be opened with IRow::Open(GUID_NULL, IID_IUnknown...)?"); } //Release all Objects SAFE_RELEASE(pIUnknown); SAFE_RELEASE(pIUnknown2); SAFE_RELEASE(pIRowset); SAFE_RELEASE(pIRowset2); if (fDifferentColumns) { // no need to do several iterations over the same column, proceed to the next one break; } } } CLEANUP: //Release all Objects SAFE_RELEASE(pIUnknown); SAFE_RELEASE(pIUnknown2); SAFE_RELEASE(pIRowset); SAFE_RELEASE(pIRowset2); TRETURN } /////////////////////////////////////////////////////////////////////////// // TCIRow::FindObject // //////////////////////////////////////////////////////////////////////////// HRESULT TCIRow::FindObject ( CRowObject* pCRowObject, IUnknown* pUnkOuter, REFGUID rguid, REFIID riid, IUnknown** ppIUnknown, DBID** ppColumnID ) { TBEGIN ASSERT(pCRowObject); ASSERT(ppIUnknown); HRESULT hr = S_OK; DBORDINAL i,cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; void* pData = NULL; if(ppColumnID) *ppColumnID = NULL; //Create the ColAccess Structures... TESTC_(hr = pCRowObject->CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG),S_OK); //Try to find an object of the specified type... for(i=0; iOpen(pUnkOuter, &rgColAccess[i].columnid, rguid, riid, ppIUnknown); //Did we find one yet? if(SUCCEEDED(hr)) { if(ppColumnID) { SAFE_ALLOC(*ppColumnID, DBID, 1); TESTC_(hr = DuplicateDBID(rgColAccess[i].columnid, *ppColumnID),S_OK); } break; } } CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(pData); return hr; } //////////////////////////////////////////////////////////////////////////// // TCIRow::Thread_VerifyGetColumns // //////////////////////////////////////////////////////////////////////////// ULONG TCIRow::Thread_VerifyGetColumns(void* pv) { THREAD_BEGIN //Thread Stack Variables TCIRow* pThis = (TCIRow*)THREAD_FUNC; CRowObject* pCRowObject = (CRowObject*)THREAD_ARG1; ASSERT(pThis); ThreadSwitch(); //Let the other thread(s) catch up //IRow::GetColumns TESTC(pThis->VerifyGetColumns(pCRowObject, FIRST_ROW, ALL_COLS_BOUND)); ThreadSwitch(); //Let the other thread(s) catch up CLEANUP: THREAD_RETURN } //////////////////////////////////////////////////////////////////////////// // TCIRow::Thread_VerifyGetSourceRowset // //////////////////////////////////////////////////////////////////////////// ULONG TCIRow::Thread_VerifyGetSourceRowset(void* pv) { THREAD_BEGIN //Thread Stack Variables TCIRow* pThis = (TCIRow*)THREAD_FUNC; ASSERT(pThis); ThreadSwitch(); //Let the other thread(s) catch up //IRow::GetColumns TESTC(pThis->VerifyGetSourceRowset(IID_IRowset)); ThreadSwitch(); //Let the other thread(s) catch up CLEANUP: THREAD_RETURN } //////////////////////////////////////////////////////////////////////////// // TCIRow::Thread_VerifyOpenWithOpenObjects // //////////////////////////////////////////////////////////////////////////// ULONG TCIRow::Thread_VerifyOpenWithOpenObjects(void* pv) { THREAD_BEGIN //Thread Stack Variables TCIRow* pThis = (TCIRow*)THREAD_FUNC; GUID rGuidType = *(GUID*)THREAD_ARG1; IID riid = *(IID*)THREAD_ARG2; CRowObject *pRowObjects = (CRowObject*)THREAD_ARG3; DWORD *pThreadIDs = (DWORD*)THREAD_ARG4; bool fDifferentColumns = *(bool*)THREAD_ARG5; ASSERT(pThis); ThreadSwitch(); //Let the other thread(s) catch up //IRow::Open TESTC(pThis->VerifyOpenWithOpenObjects(rGuidType, riid, pRowObjects, pThreadIDs, fDifferentColumns)); ThreadSwitch(); //Let the other thread(s) catch up CLEANUP: THREAD_RETURN } // {{ TCW_TEST_CASE_MAP(TCIRow_IUnknown) //*----------------------------------------------------------------------- // @class IRow IUnknown scenarios // class TCIRow_IUnknown : public TCIRow { private: // @cmember Static array of variations DECLARE_TEST_CASE_DATA(); public: // {{ TCW_DECLARE_FUNCS // @cmember Execution Routine DECLARE_TEST_CASE_FUNCS(TCIRow_IUnknown,TCIRow); // }} 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(TCIRow_IUnknown) #define THE_CLASS TCIRow_IUnknown BEG_TEST_CASE(TCIRow_IUnknown, TCIRow, L"IRow 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(TCIRow_GetColumns) //*----------------------------------------------------------------------- // @class IRow::GetColumns // class TCIRow_GetColumns : public TCIRow { private: // @cmember Static array of variations DECLARE_TEST_CASE_DATA(); public: // {{ TCW_DECLARE_FUNCS // @cmember Execution Routine DECLARE_TEST_CASE_FUNCS(TCIRow_GetColumns,TCIRow); // }} TCW_DECLARE_FUNCS_END // @cmember Initialization Routine virtual BOOL Init(); // @cmember Termination Routine virtual BOOL Terminate(); BOOL FindColumnDBTYPE_BYTES(DBSTATUS status, DBCOUNTITEM *pRowIndex, DBORDINAL *pColIndex); int UnalignedBuferTest(DBSTATUS columnStatus); // {{ TCW_TESTVARS() // @cmember GetColumns - All columns - no BLOBs int Variation_1(); // @cmember GetColumns - All Columns - BLOBs int Variation_2(); // @cmember GetColumns - same column bound numerous times int Variation_3(); // @cmember GetColumns - BLOB Columns only int Variation_4(); // @cmember GetColumns - Each Column Seperatly int Variation_5(); // @cmember GetColumns - Asking for just Rowset columns int Variation_6(); // @cmember GetColumns - Asking for just Extra Row Columns int Variation_7(); // @cmember GetColumns - IUnknown Columns - native int Variation_8(); // @cmember Empty int Variation_9(); // @cmember GetColumns - Not Binding Value, pData is NULL int Variation_10(); // @cmember GetColumns - Value not bound for some columns int Variation_11(); // @cmember Empty int Variation_12(); // @cmember Vectors - Some valid, some non-existent columns - DB_S_ERRORSOCCURRED int Variation_13(); // @cmember Vectors - All non-existent columns - DB_E_ERRORSOCCURRED int Variation_14(); // @cmember Vectors - No Vector Columns - S_OK int Variation_15(); // @cmember Vectors - No Vectors and Non-Existent Columns - DB_E_ERRORSOCCURRED int Variation_16(); // @cmember Vectors - Only Vector Columns - S_OK int Variation_17(); // @cmember Vectors - Only Non-Existent Vector Columns - DB_E_ERRORSOCCURRED int Variation_18(); // @cmember Vectors - Valid Vectors and Non-Existent Columns - DB_S_ERRORSOCCURRED int Variation_19(); // @cmember Vectors - Valid Non-Vectors and Non-Existent Vector Columns - DB_S_ERRORSOCCURRED int Variation_20(); // @cmember Empty int Variation_21(); // @cmember Boundary - 0 columns -[0, NULL] and [0, valid] no-op int Variation_22(); // @cmember Boundary - [Valid, NULL] - E_INVALIDARG int Variation_23(); // @cmember Empty int Variation_24(); // @cmember Boundary - columnid - all valid dbkinds int Variation_25(); // @cmember Boundary - columnid - invalid dbkinds int Variation_26(); // @cmember Boundary - columnid - invalid [but close to original] dbkinds int Variation_27(); // @cmember Boundary - cbMaxLen - ignored for fixed length types int Variation_28(); // @cmember Boundary - cbMaxLen - DBSTATUS_S_TRUNCATION int Variation_29(); // @cmember Boundary - cbMaxLen - invalid int Variation_30(); // @cmember Empty int Variation_31(); // @cmember Boundary - wType - all valid types and modifieres int Variation_32(); // @cmember Boundary - wType - invalid types and invalid type modifiers int Variation_33(); // @cmember Empty int Variation_34(); // @cmember Boundary - bPrecision - make sure ignored on input for all types, except NUMERIC. int Variation_35(); // @cmember Boundary - bScale - make sure ignored on input for all types, except NUMERIC. int Variation_36(); // @cmember Boundary - Output Only - make sure cbDataLen, dwStatus, dwReserverd are ignored on input int Variation_37(); // @cmember Boundary - Input - Make sure all pointers and input args are not changed on output, pData pointer, columnid [including all union pointers], cbMaxLen, dwReserved, wType. int Variation_38(); // @cmember Empty int Variation_39(); // @cmember Supply unaligned buffer for non-NULL bytes value int Variation_40(); // @cmember Empty int Variation_41(); // @cmember Empty int Variation_42(); // @cmember Buffered Mode - All Columns - no BLOBs int Variation_43(); // @cmember Buffered Mode - All Columns - BLOBs int Variation_44(); // @cmember Buffered Mode - All Columns - Just extra columns int Variation_45(); // @cmember Empty int Variation_46(); // @cmember Aggregation - Command - > Row int Variation_47(); // @cmember Aggregation - Session - > Row int Variation_48(); // @cmember Aggregation - Rowset -> Row int Variation_49(); // @cmember Empty int Variation_50(); // @cmember Empty int Variation_51(); // @cmember Properties - DBPROP_IRow int Variation_52(); // @cmember Properties - DBPROP_OLEOBJECTS - DBPROPVAL_OO_ROWOBJECT int Variation_53(); // @cmember Properties - DBPROP_OLEOBJECTS - DBPROPVAL_OO_SINGLETON int Variation_54(); // @cmember Empty int Variation_55(); // @cmember Properties - All Row Object Properties int Variation_56(); // @cmember Properties - All Row Object Properties Optional int Variation_57(); // @cmember Empty int Variation_58(); // @cmember Properties - Rowset Properties int Variation_59(); // @cmember Empty int Variation_60(); // @cmember Threads - GetColumns seperate threads int Variation_61(); // @cmember Empty int Variation_62(); // @cmember Boundary - DB_E_DELETEDROW int Variation_63(); // @cmember Boundary - DB_E_DELETEDROW - Bufferred Mode int Variation_64(); // }} TCW_TESTVARS_END } ; // {{ TCW_TESTCASE(TCIRow_GetColumns) #define THE_CLASS TCIRow_GetColumns BEG_TEST_CASE(TCIRow_GetColumns, TCIRow, L"IRow::GetColumns") TEST_VARIATION(1, L"GetColumns - All columns - no BLOBs") TEST_VARIATION(2, L"GetColumns - All Columns - BLOBs") TEST_VARIATION(3, L"GetColumns - same column bound numerous times") TEST_VARIATION(4, L"GetColumns - BLOB Columns only") TEST_VARIATION(5, L"GetColumns - Each Column Seperatly") TEST_VARIATION(6, L"GetColumns - Asking for just Rowset columns") TEST_VARIATION(7, L"GetColumns - Asking for just Extra Row Columns") TEST_VARIATION(8, L"GetColumns - IUnknown Columns - native") TEST_VARIATION(9, L"Empty") TEST_VARIATION(10, L"GetColumns - Not Binding Value, pData is NULL") TEST_VARIATION(11, L"GetColumns - Value not bound for some columns") TEST_VARIATION(12, L"Empty") TEST_VARIATION(13, L"Vectors - Some valid, some non-existent columns - DB_S_ERRORSOCCURRED") TEST_VARIATION(14, L"Vectors - All non-existent columns - DB_E_ERRORSOCCURRED") TEST_VARIATION(15, L"Vectors - No Vector Columns - S_OK") TEST_VARIATION(16, L"Vectors - No Vectors and Non-Existent Columns - DB_E_ERRORSOCCURRED") TEST_VARIATION(17, L"Vectors - Only Vector Columns - S_OK") TEST_VARIATION(18, L"Vectors - Only Non-Existent Vector Columns - DB_E_ERRORSOCCURRED") TEST_VARIATION(19, L"Vectors - Valid Vectors and Non-Existent Columns - DB_S_ERRORSOCCURRED") TEST_VARIATION(20, L"Vectors - Valid Non-Vectors and Non-Existent Vector Columns - DB_S_ERRORSOCCURRED") TEST_VARIATION(21, L"Empty") TEST_VARIATION(22, L"Boundary - 0 columns -[0, NULL] and [0, valid] no-op") TEST_VARIATION(23, L"Boundary - [Valid, NULL] - E_INVALIDARG") TEST_VARIATION(24, L"Empty") TEST_VARIATION(25, L"Boundary - columnid - all valid dbkinds") TEST_VARIATION(26, L"Boundary - columnid - invalid dbkinds") TEST_VARIATION(27, L"Boundary - columnid - invalid [but close to original] dbkinds") TEST_VARIATION(28, L"Boundary - cbMaxLen - ignored for fixed length types") TEST_VARIATION(29, L"Boundary - cbMaxLen - DBSTATUS_S_TRUNCATION") TEST_VARIATION(30, L"Boundary - cbMaxLen - invalid") TEST_VARIATION(31, L"Empty") TEST_VARIATION(32, L"Boundary - wType - all valid types and modifieres") TEST_VARIATION(33, L"Boundary - wType - invalid types and invalid type modifiers") TEST_VARIATION(34, L"Empty") TEST_VARIATION(35, L"Boundary - bPrecision - make sure ignored on input for all types, except NUMERIC.") TEST_VARIATION(36, L"Boundary - bScale - make sure ignored on input for all types, except NUMERIC.") TEST_VARIATION(37, L"Boundary - Output Only - make sure cbDataLen, dwStatus, dwReserverd are ignored on input") TEST_VARIATION(38, L"Boundary - Input - Make sure all pointers and input args are not changed on output, pData pointer, columnid [including all union pointers], cbMaxLen, dwReserved, wType.") TEST_VARIATION(39, L"Empty") TEST_VARIATION(40, L"Supply unaligned buffer for non-NULL bytes value") TEST_VARIATION(41, L"Empty") TEST_VARIATION(42, L"Empty") TEST_VARIATION(43, L"Buffered Mode - All Columns - no BLOBs") TEST_VARIATION(44, L"Buffered Mode - All Columns - BLOBs") TEST_VARIATION(45, L"Buffered Mode - All Columns - Just extra columns") TEST_VARIATION(46, L"Empty") TEST_VARIATION(47, L"Aggregation - Command - > Row") TEST_VARIATION(48, L"Aggregation - Session - > Row") TEST_VARIATION(49, L"Aggregation - Rowset -> Row") TEST_VARIATION(50, L"Empty") TEST_VARIATION(51, L"Empty") TEST_VARIATION(52, L"Properties - DBPROP_IRow") TEST_VARIATION(53, L"Properties - DBPROP_OLEOBJECTS - DBPROPVAL_OO_ROWOBJECT") TEST_VARIATION(54, L"Properties - DBPROP_OLEOBJECTS - DBPROPVAL_OO_SINGLETON") TEST_VARIATION(55, L"Empty") TEST_VARIATION(56, L"Properties - All Row Object Properties") TEST_VARIATION(57, L"Properties - All Row Object Properties Optional") TEST_VARIATION(58, L"Empty") TEST_VARIATION(59, L"Properties - Rowset Properties") TEST_VARIATION(60, L"Empty") TEST_VARIATION(61, L"Threads - GetColumns seperate threads") TEST_VARIATION(62, L"Empty") TEST_VARIATION(63, L"Boundary - DB_E_DELETEDROW") TEST_VARIATION(64, L"Boundary - DB_E_DELETEDROW - Bufferred Mode") END_TEST_CASE() #undef THE_CLASS // }} TCW_TESTCASE_END // }} TCW_TEST_CASE_MAP_END // {{ TCW_TEST_CASE_MAP(TCIRow_GetSourceRowset) //*----------------------------------------------------------------------- // @class IRow::GetSourceRowset // class TCIRow_GetSourceRowset : public TCIRow { private: // @cmember Static array of variations DECLARE_TEST_CASE_DATA(); public: // {{ TCW_DECLARE_FUNCS // @cmember Execution Routine DECLARE_TEST_CASE_FUNCS(TCIRow_GetSourceRowset,TCIRow); // }} TCW_DECLARE_FUNCS_END // @cmember Initialization Routine virtual BOOL Init(); // @cmember Termination Routine virtual BOOL Terminate(); // {{ TCW_TESTVARS() // @cmember riid - All Mandatory interfaces int Variation_1(); // @cmember Empty int Variation_2(); // @cmember Optional Args - [any riid, NULL, NULL] - S_OK int Variation_3(); // @cmember Optional Args - [any riid, NULL, valid] - S_OK with hRow int Variation_4(); // @cmember Optional Args - [IID_IUnknown, valid, NULL] - S_OK with Rowset int Variation_5(); // @cmember Optional Args - [IID_IRowset, valid, valid] - S_OK with Rowset and hRow int Variation_6(); // @cmember Empty int Variation_7(); // @cmember Sequence - Execute -> Row -> GetSourceRowset int Variation_8(); // @cmember Sequence - Execute -> Rowset -> Row -> GetSourceRowset int Variation_9(); // @cmember Sequence - OpenRowset -> Row -> Release Rowset -> GetSourceRowset int Variation_10(); // @cmember Sequence - OpenRowset -> Rowset -> Row -> Release Rowset -> GetSourceRowset int Variation_11(); // @cmember Empty int Variation_12(); // @cmember Multiple - GetSourceRowset from numerous child row objects int Variation_13(); // @cmember Multiple - Numerous Rowsets open, verify correct parent int Variation_14(); // @cmember Empty int Variation_15(); // @cmember Aggregation - Rowset -> Agg Row -> GetSourceRowset int Variation_16(); // @cmember Aggregation - Agg Rowset -> Row -> GetSourceRowset int Variation_17(); // @cmember Empty int Variation_18(); // @cmember Threads - GetSourceRowset int Variation_19(); // }} TCW_TESTVARS_END } ; // {{ TCW_TESTCASE(TCIRow_GetSourceRowset) #define THE_CLASS TCIRow_GetSourceRowset BEG_TEST_CASE(TCIRow_GetSourceRowset, TCIRow, L"IRow::GetSourceRowset") TEST_VARIATION(1, L"riid - All Mandatory interfaces") TEST_VARIATION(2, L"Empty") TEST_VARIATION(3, L"Optional Args - [any riid, NULL, NULL] - S_OK") TEST_VARIATION(4, L"Optional Args - [any riid, NULL, valid] - S_OK with hRow") TEST_VARIATION(5, L"Optional Args - [IID_IUnknown, valid, NULL] - S_OK with Rowset") TEST_VARIATION(6, L"Optional Args - [IID_IRowset, valid, valid] - S_OK with Rowset and hRow") TEST_VARIATION(7, L"Empty") TEST_VARIATION(8, L"Sequence - Execute -> Row -> GetSourceRowset") TEST_VARIATION(9, L"Sequence - Execute -> Rowset -> Row -> GetSourceRowset") TEST_VARIATION(10, L"Sequence - OpenRowset -> Row -> Release Rowset -> GetSourceRowset") TEST_VARIATION(11, L"Sequence - OpenRowset -> Rowset -> Row -> Release Rowset -> GetSourceRowset") TEST_VARIATION(12, L"Empty") TEST_VARIATION(13, L"Multiple - GetSourceRowset from numerous child row objects") TEST_VARIATION(14, L"Multiple - Numerous Rowsets open, verify correct parent") TEST_VARIATION(15, L"Empty") TEST_VARIATION(16, L"Aggregation - Rowset -> Agg Row -> GetSourceRowset") TEST_VARIATION(17, L"Aggregation - Agg Rowset -> Row -> GetSourceRowset") TEST_VARIATION(18, L"Empty") TEST_VARIATION(19, L"Threads - GetSourceRowset") END_TEST_CASE() #undef THE_CLASS // }} TCW_TESTCASE_END // }} TCW_TEST_CASE_MAP_END // {{ TCW_TEST_CASE_MAP(TCIRow_Open) //*----------------------------------------------------------------------- // @class IRow::Open // class TCIRow_Open : public TCIRow { private: // @cmember Static array of variations DECLARE_TEST_CASE_DATA(); public: // {{ TCW_DECLARE_FUNCS // @cmember Execution Routine DECLARE_TEST_CASE_FUNCS(TCIRow_Open,TCIRow); // }} TCW_DECLARE_FUNCS_END // @cmember Initialization Routine virtual BOOL Init(); // @cmember Termination Routine virtual BOOL Terminate(); // {{ TCW_TESTVARS() // @cmember GUID_NULL - All columns as Default Object int Variation_1(); // @cmember DBGUID_STREAM - All Mandatory and Optional TStream interfaces int Variation_2(); // @cmember DBGUID_STREAM - Compare data with expected int Variation_3(); // @cmember DBGUID_STREAM - Twice on the same column int Variation_4(); // @cmember DBGUID_STREAM - Multiple Objects open on different columns int Variation_5(); // @cmember DBGUID_STREAM - Bufferred Mode int Variation_6(); // @cmember Empty int Variation_7(); // @cmember DBGUID_ROW - All Mandatory and Optional TRow interfaces int Variation_8(); // @cmember DBGUID_ROW - Get all row columns and verify int Variation_9(); // @cmember DBGUID_ROW - GetSourceRowset int Variation_10(); // @cmember DBGUID_ROW - Twice on the same column int Variation_11(); // @cmember DBGUID_ROW - Multiple Objects open on different columns int Variation_12(); // @cmember DBGUID_ROW - Bufferred Mode int Variation_13(); // @cmember Empty int Variation_14(); // @cmember DBGUID_ROWSET - All Mandatory and Optional TRowset interfaces int Variation_15(); // @cmember DBGUID_ROWSET - Twice on the same column int Variation_16(); // @cmember DBGUID_ROWSET - Buffered mode int Variation_17(); // @cmember Empty int Variation_18(); // @cmember DEFAULTSTREAM int Variation_19(); // @cmember DEFAULTSTREAM - Buffered mode int Variation_20(); // @cmember Empty int Variation_21(); // @cmember Boundary - E_INVALIDARG int Variation_22(); // @cmember Boundary - DB_E_BADCOLUMNID - invalid DBID int Variation_23(); // @cmember Boundary - DB_E_BADCOLUMNID - invalid [but close to original] DBID int Variation_24(); // @cmember Boundary - DB_E_BADCOLUMNID - shortcut DBID that doesn't exist int Variation_25(); // @cmember Boundary - DB_E_OBJECTMISMATCH int Variation_26(); // @cmember Boundary - DB_E_OBJECTOPEN int Variation_27(); // @cmember Boundary - DB_E_NOTFOUND int Variation_28(); // @cmember Boundary - DB_E_DELETEDROW int Variation_29(); // @cmember Empty int Variation_30(); // @cmember Stream Object - Read the data in chunks int Variation_31(); // @cmember Empty int Variation_32(); // @cmember Aggregation - Row -> Open -> GetSourceRow int Variation_33(); // @cmember Empty int Variation_34(); // @cmember Threads - Open over the same column int Variation_35(); // @cmember Threads - Open over different columns int Variation_36(); // }} TCW_TESTVARS_END } ; // {{ TCW_TESTCASE(TCIRow_Open) #define THE_CLASS TCIRow_Open BEG_TEST_CASE(TCIRow_Open, TCIRow, L"IRow::Open") TEST_VARIATION(1, L"GUID_NULL - All columns as Default Object") TEST_VARIATION(2, L"DBGUID_STREAM - All Mandatory and Optional TStream interfaces") TEST_VARIATION(3, L"DBGUID_STREAM - Compare data with expected") TEST_VARIATION(4, L"DBGUID_STREAM - Twice on the same column") TEST_VARIATION(5, L"DBGUID_STREAM - Multiple Objects open on different columns") TEST_VARIATION(6, L"DBGUID_STREAM - Bufferred Mode") TEST_VARIATION(7, L"Empty") TEST_VARIATION(8, L"DBGUID_ROW - All Mandatory and Optional TRow interfaces") TEST_VARIATION(9, L"DBGUID_ROW - Get all row columns and verify") TEST_VARIATION(10, L"DBGUID_ROW - GetSourceRowset") TEST_VARIATION(11, L"DBGUID_ROW - Twice on the same column") TEST_VARIATION(12, L"DBGUID_ROW - Multiple Objects open on different columns") TEST_VARIATION(13, L"DBGUID_ROW - Bufferred Mode") TEST_VARIATION(14, L"Empty") TEST_VARIATION(15, L"DBGUID_ROWSET - All Mandatory and Optional TRowset interfaces") TEST_VARIATION(16, L"DBGUID_ROWSET - Twice on the same column") TEST_VARIATION(17, L"DBGUID_ROWSET - Buffered mode") TEST_VARIATION(18, L"Empty") TEST_VARIATION(19, L"DEFAULTSTREAM") TEST_VARIATION(20, L"DEFAULTSTREAM - Buffered mode") TEST_VARIATION(21, L"Empty") TEST_VARIATION(22, L"Boundary - E_INVALIDARG") TEST_VARIATION(23, L"Boundary - DB_E_BADCOLUMNID - invalid DBID") TEST_VARIATION(24, L"Boundary - DB_E_BADCOLUMNID - invalid [but close to original] DBID") TEST_VARIATION(25, L"Boundary - DB_E_BADCOLUMNID - shortcut DBID that doesn't exist") TEST_VARIATION(26, L"Boundary - DB_E_OBJECTMISMATCH") TEST_VARIATION(27, L"Boundary - DB_E_OBJECTOPEN") TEST_VARIATION(28, L"Boundary - DB_E_NOTFOUND") TEST_VARIATION(29, L"Boundary - DB_E_DELETEDROW") TEST_VARIATION(30, L"Empty") TEST_VARIATION(31, L"Stream Object - Read the data in chunks") TEST_VARIATION(32, L"Empty") TEST_VARIATION(33, L"Aggregation - Row -> Open -> GetSourceRow") TEST_VARIATION(34, L"Empty") TEST_VARIATION(35, L"Threads - Open over the same column") TEST_VARIATION(36, L"Threads - Open over different columns") END_TEST_CASE() #undef THE_CLASS // }} TCW_TESTCASE_END // }} TCW_TEST_CASE_MAP_END // {{ TCW_TEST_CASE_MAP(TCTransactions) //*----------------------------------------------------------------------- // @class IRow 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"IRow 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(5, ThisModule, gwszModuleDescrip) TEST_CASE(1, TCIRow_IUnknown) TEST_CASE(2, TCIRow_GetColumns) TEST_CASE(3, TCIRow_GetSourceRowset) TEST_CASE(4, TCIRow_Open) TEST_CASE(5, 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; ISequentialStream* pISeqStream = NULL; IRowsetInfo* pIRowsetInfo = INVALID(IRowsetInfo*); HROW hSourceRow = NULL; //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); //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::GetColumns TESTC(RowObjectA.VerifyGetColumns(FIRST_ROW, RowsetA.pTable())); //IRow::GetSourceRowset TESTC_(RowObjectA.GetSourceRowset(IID_IRowsetInfo, (IUnknown**)&pIRowsetInfo, NULL), S_OK); TESTC(DefaultObjectTesting(pIRowsetInfo, ROWSET_INTERFACE)); //IRow::Open (open the default stream - note it may not exist for every row) //NOTE: Our helper takes care of all validation of the returned object... TEST2C_(RowObjectA.Open(NULL, &DBROWCOL_DEFAULTSTREAM, DBGUID_STREAM, IID_ISequentialStream, (IUnknown**)&pISeqStream),S_OK, DB_E_BADCOLUMNID); } else { //zombie //IRow::GetColumns TESTC_(RowObjectA.GetColumns(RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess),E_UNEXPECTED); //Make sure it NULLs the output params on error... hSourceRow = INVALID(HROW); pIRowsetInfo = INVALID(IRowsetInfo*); //IRow::GetSourceRowset TESTC_(RowObjectA.GetSourceRowset(IID_IRowsetInfo, (IUnknown**)&pIRowsetInfo, &hSourceRow), E_UNEXPECTED); TESTC(hSourceRow == NULL); TESTC(pIRowsetInfo == NULL); //IRow::GetSourceRowset //This time not asking for an HROW, as its more difficult for the provider to determine //zombie, if just getting a parent object, vs. row handle (ie: ConfProv) TESTC_(RowObjectA.GetSourceRowset(IID_IRowsetInfo, (IUnknown**)&pIRowsetInfo, NULL), E_UNEXPECTED); TESTC(pIRowsetInfo == NULL); //IRow::Open (open the default stream - note it may not exist for every row) //NOTE: Our helper takes care of all validation of the returned object... TESTC_(RowObjectA.Open(NULL, &DBROWCOL_DEFAULTSTREAM, DBGUID_STREAM, IID_ISequentialStream, (IUnknown**)&pISeqStream), E_UNEXPECTED); TESTC(pISeqStream == NULL); } CLEANUP: SAFE_RELEASE(pIGetRow); SAFE_RELEASE(pISeqStream); if(pIRowsetInfo != INVALID(IRowsetInfo*)) SAFE_RELEASE(pIRowsetInfo); //clean up. CleanUpTransaction(fRetaining ? S_OK : XACT_E_NOTRANSACTION); TRETURN } // {{ TCW_TC_PROTOTYPE(TCIRow_IUnknown) //*----------------------------------------------------------------------- //| Test Case: TCIRow_IUnknown - IRow IUnknown scenarios //| Created: 8/5/98 //*----------------------------------------------------------------------- //*----------------------------------------------------------------------- // @mfunc TestCase Initialization Routine // // @rdesc TRUE or FALSE // BOOL TCIRow_IUnknown::Init() { // {{ TCW_INIT_BASECLASS_CHECK if(TCIRow::Init()) // }} { return TRUE; } return FALSE; } // {{ TCW_VAR_PROTOTYPE(1) //*----------------------------------------------------------------------- // @mfunc IUnknown - QI Mandatory Interfaces // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_IUnknown::Variation_1() { //Do some default IUnknown interface testing return DefaultObjectTesting(m_pCRowObject->pIRow(), ROW_INTERFACE); } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(2) //*----------------------------------------------------------------------- // @mfunc IUnknown - QI Optional Interfaces // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_IUnknown::Variation_2() { //Do some default IUnknown interface testing return DefaultObjectTesting(m_pCRowObject->pIRow(), ROW_INTERFACE); } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(3) //*----------------------------------------------------------------------- // @mfunc IUnknown - AddRef / Release // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_IUnknown::Variation_3() { //Do some default IUnknown interface testing return DefaultObjectTesting(m_pCRowObject->pIRow(), ROW_INTERFACE); } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_TERMINATE_METHOD //*----------------------------------------------------------------------- // @mfunc TestCase Termination Routine // // @rdesc TEST_PASS or TEST_FAIL // BOOL TCIRow_IUnknown::Terminate() { // {{ TCW_TERM_BASECLASS_CHECK2 return(TCIRow::Terminate()); } // }} // }} TCW_TERMINATE_METHOD_END // }} TCW_TC_PROTOTYPE_END // {{ TCW_TC_PROTOTYPE(TCIRow_GetColumns) //*----------------------------------------------------------------------- //| Test Case: TCIRow_GetColumns - IRow::GetColumns //| Created: 8/5/98 //*----------------------------------------------------------------------- //*----------------------------------------------------------------------- // @mfunc TestCase Initialization Routine // // @rdesc TRUE or FALSE // BOOL TCIRow_GetColumns::Init() { // {{ TCW_INIT_BASECLASS_CHECK if(TCIRow::Init()) // }} { return TRUE; } return FALSE; } // {{ TCW_VAR_PROTOTYPE(1) //*----------------------------------------------------------------------- // @mfunc GetColumns - All columns - no BLOBs // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_1() { TBEGIN //Loop through all the rows in the rowset, verify the columns... TESTC(VerifyGetColumnsAllRows(NULL, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(2) //*----------------------------------------------------------------------- // @mfunc GetColumns - All Columns - BLOBs // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_2() { TBEGIN //Loop through all the rows in the rowset, verify the columns... TESTC(VerifyGetColumnsAllRows(NULL, ALL_COLS_BOUND, BLOB_LONG)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(3) //*----------------------------------------------------------------------- // @mfunc GetColumns - same column bound numerous times // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_3() { 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. CRowset RowsetA; RowsetA.SetSettableProperty(DBPROP_ACCESSORDER, DBPROPSET_ROWSET, (void*)DBPROPVAL_AO_RANDOM, DBTYPE_I4); TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK); //Get the ColumnInfo TESTC(VerifyInterface(m_pCRowObject->pIRow(), 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; ipIRow(), IID_IColumnsInfo, ROW_INTERFACE, (IUnknown**)&pIColumnsInfo)); TESTC_(pIColumnsInfo->GetColumnInfo(&cColumns, &rgColumnInfo, &pStringBuffer),S_OK); //Loop through each column seperatly... for(i=0; iiOrdinal)); //While were doing each column seperately also only bind status and length TESTC(VerifyGetColumnsAllRows(NULL, USE_COLS_TO_BIND_ARRAY, BLOB_LONG, FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, 1, &pColInfo->iOrdinal, DBPART_LENGTH|DBPART_STATUS)); //Also for BLOBS bind (seperatly) as streams if(pColInfo->dwFlags & DBCOLUMNFLAGS_ISLONG) { TESTC(VerifyGetColumnsAllRows(NULL, USE_COLS_TO_BIND_ARRAY, BLOB_IID_IUNKNOWN, FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, 1, &pColInfo->iOrdinal)); //While were doing each column seperately also only bind status and length TESTC(VerifyGetColumnsAllRows(NULL, USE_COLS_TO_BIND_ARRAY, BLOB_IID_IUNKNOWN, FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, 1, &pColInfo->iOrdinal, DBPART_LENGTH|DBPART_STATUS)); } } CLEANUP: SAFE_FREE(rgColumnInfo); SAFE_FREE(pStringBuffer); SAFE_RELEASE(pIColumnsInfo); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(6) //*----------------------------------------------------------------------- // @mfunc GetColumns - Asking for just Rowset columns // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_6() { TBEGIN HRESULT hr = S_OK; DBORDINAL cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Create ColAccess structures from the Rowset bindings TESTC_(hr = RowObjectA.BindingsToColAccess(m_cBindings, m_rgBinding, m_pData, &cColAccess, &rgColAccess),S_OK); //IRow::GetColumns TESTC_(hr = RowObjectA.GetColumns(cColAccess, rgColAccess),S_OK); //Compare Data for this row object TESTC(RowObjectA.CompareColAccess(cColAccess, rgColAccess, FIRST_ROW, pTable())); CLEANUP: FreeColAccess(cColAccess, rgColAccess); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(7) //*----------------------------------------------------------------------- // @mfunc GetColumns - Asking for just Extra Row Columns // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_7() { TBEGIN HRESULT hr = S_OK; DBORDINAL cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; void* pData = NULL; DBORDINAL cColumns = 0; DBORDINAL* rgColOrdinals = NULL; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Obtain the just the Extra columns TEST2C_(hr = RowObjectA.GetExtraColumnInfo(&cColumns, NULL, NULL, &rgColOrdinals),S_OK,DB_E_NOSOURCEOBJECT); if(hr == DB_E_NOSOURCEOBJECT) { odtLog<GetColumns(0, INVALID(DBCOLUMNACCESS*)), S_OK); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(23) //*----------------------------------------------------------------------- // @mfunc Boundary - [Valid, NULL] - E_INVALIDARG // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_23() { TBEGIN //GetColumns - with (Valid, NULL)- E_INVALIDARG TESTC_(m_pCRowObject->GetColumns(5, NULL), E_INVALIDARG); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(24) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_24() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(25) //*----------------------------------------------------------------------- // @mfunc Boundary - columnid - all valid dbkinds // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_25() { TBEGIN DBORDINAL i,cColInvalid = 0; DBCOLUMNACCESS* rgColInvalid = NULL; void* pData = NULL; ULONG cNonVectors = 0; HRESULT hrExpected = S_OK; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Create the ColAccess Structures (for all columns)... TESTC_(RowObjectA.CreateColAccess(&cColInvalid, &rgColInvalid, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG),S_OK); //Loop through all columns for(i=0; icolumnid, FALSE/*fDrop*/); pColAccess->columnid.eKind = (ULONG)i % (DBKIND_GUID+1); //Now Create a unique colid for this type... TESTC_(CreateUniqueDBID(&pColAccess->columnid),S_OK); } //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColInvalid, rgColInvalid), cColInvalid ? DB_E_ERRORSOCCURRED : S_OK); //Verify Status' for(i=0; icolumnid, FALSE/*fDrop*/); pColAccess->columnid.eKind = DBKIND_GUID+1; } //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColInvalid, rgColInvalid), cColInvalid ? DB_E_ERRORSOCCURRED : S_OK); //Verify Status' for(i=0; ieKind) { case DBKIND_GUID_NAME: case DBKIND_PGUID_NAME: { GUID guid; //Create a "unique" string SAFE_FREE(pColumnID->uName.pwszName); //For every other "name" column - well use NULL if(iCol%2) { TESTC_(CoCreateGuid(&guid),S_OK); TESTC_(StringFromCLSID(guid, &pColumnID->uName.pwszName),S_OK); } break; } default: { //Otherwise just create a completely unique name... //For two-part it changes the GUID, so all we really have left is to verify //that only changing the name is caught... TESTC_(CreateUniqueDBID(pColumnID, TRUE/*fInitialize*/),S_OK); break; } }; } //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColInvalid, rgColInvalid), cColInvalid ? DB_E_ERRORSOCCURRED : S_OK); //Verify Status' for(iCol=0; iColwType) || (pColAccess->wType & (DBTYPE_BYREF|DBTYPE_ARRAY|DBTYPE_VECTOR))) { //NOTE: We want to vary this value, since -1 (ULONG_MAX) might cause problems if there //using this value for allocations, and 0 might cause problems is using for remoting //for the next location in the buffer, etc. We also want to vary the value since the //proivder / remoting might have special checks against fixed values for protection... pColAccess->cbMaxLen = i ? (-1/*ULONG_MAX*//i) : 0; //Protect against divide by 0 } } //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColAccess, rgColAccess),S_OK); //Compare Data for this row object TESTC(RowObjectA.CompareColAccess(cColAccess, rgColAccess, FIRST_ROW, pTable())); CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(pData); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(29) //*----------------------------------------------------------------------- // @mfunc Boundary - cbMaxLen - DBSTATUS_S_TRUNCATION // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_29() { TBEGIN DBORDINAL i,cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; void* pData = NULL; ULONG cTruncated = 0; HRESULT hrExpected = S_OK; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Create the ColAccess Structures (for all columns)... TESTC_(RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG),S_OK); //Loop through all columns for(i=0; iwType)) { //NOTE: cbMaxLength is ignored for fixed length types... pColAccess->cbMaxLen = 0; } else { //NOTE: We want to vary this value, since it may have different effects on different //types and setting it to 0 may go through a different code path than ~0, etc... pColAccess->cbMaxLen = cTruncated; if(pColAccess->wType == DBTYPE_STR || pColAccess->wType == DBTYPE_WSTR) { //We only increment if a string, since we want the first string data //to have a 0 byte cbMaxLen (not enough for a NULL terminator) cTruncated++; //NOTE: Truncation is considered a "warning" and not an error. So normally you //would expect S_OK to be returned, but since we set the first Variable Length //column to cbMaxLen=0, this should be DataOverFlow, since their is not even enough //room for the NULL terminator, so if the provider actually returns "Truncation" the //consumer would crash since their is not null terminator, and would be whatever was left //in the buffer... hrExpected = (cTruncated==cColAccess) ? DB_E_ERRORSOCCURRED : DB_S_ERRORSOCCURRED; } } } //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColAccess, rgColAccess), hrExpected); //Verify the returned status, and data... for(i=0; idwStatus) { case DBSTATUS_S_OK: //NOTE: cbMaxLength is ignored for fixed length types... if(!IsFixedLength(pColAccess->wType)) TESTC(pColAccess->cbDataLen <= pColAccess->cbMaxLen); break; case DBSTATUS_S_ISNULL: //NULL data is an exception since it doesn't matter what cbMaxLen was... break; case DBSTATUS_S_TRUNCATED: //NOTE: cbMaxLength is ignored for fixed length types... //NOTE: We have to check "cbMaxLen" since cbDataLen is the "true" untruncated //length of the actual data - if there was engouh room... TESTC(!IsFixedLength(pColAccess->wType)); TESTC(pColAccess->cbDataLen >= pColAccess->cbMaxLen); //Make sure there was enough room for the _entire_ NULL Terminator //(ie: 2 bytes for the WCHAR NULL terminator) if(pColAccess->wType == DBTYPE_STR) TESTC(pColAccess->cbMaxLen >= sizeof(CHAR)); if(pColAccess->wType == DBTYPE_WSTR) TESTC(pColAccess->cbMaxLen >= sizeof(WCHAR)); break; case DBSTATUS_E_DATAOVERFLOW: //NOTE: Truncation is considered a "warning" and not an error. So normally you //would expect S_OK to be returned, but since we set the first Variable Length //column to cbMaxLen=0, this should be DataOverFlow, since their is not even enough //room for the NULL terminator, so if the provider actually returns "Truncation" the //consumer would crash since their is not null terminator, and would be whatever was left //in the buffer... //NOTE: We have to check "cbMaxLen" since cbDataLen is the "true" untruncated //length of the actual data - if there was engouh room... TESTC(!IsFixedLength(pColAccess->wType)); TESTC(pColAccess->cbMaxLen == 0 || (pColAccess->wType == DBTYPE_WSTR && pColAccess->cbMaxLenCanConvert(pColAccess->wType, pColAccess->wType | DBTYPE_VECTOR, DBCONVERTFLAGS_COLUMN),S_OK,S_FALSE); if(hr != S_OK) cInvalid++; } //IRow::GetColumns TEST3C_(hr = RowObjectA.GetColumns(cColAccess, rgColAccess), S_OK, DB_S_ERRORSOCCURRED, DB_E_ERRORSOCCURRED); //Possibilities: //1. Everything can be converted fine (cInvalid==0) - S_OK //2. Some column could be converted but not all - DB_S_ERROROCCURRED //3. All columns coulnd not be converted - DB_E_ERRORSOCCURRED //The exception is that some column even though indicated could not be converted, could still //be convergted if the status was ISNULL - since now conversion is required for this senario... //Thats why we allow S_OK in all the following senarios... if(cInvalid == 0) TESTC_(hr, S_OK); if(cInvalid < cColAccess) TEST2C_(hr, S_OK, DB_S_ERRORSOCCURRED); if(cInvalid && cInvalid == cColAccess) TEST3C_(hr, S_OK, DB_S_ERRORSOCCURRED, DB_E_ERRORSOCCURRED); //Loop through all columns for(i=0; idwStatus == DBSTATUS_S_OK || pColAccess->dwStatus == DBSTATUS_S_ISNULL) { //Verify the data returned (successfully converted this) TESTC(RowObjectA.CompareColAccess(1, pColAccess, FIRST_ROW, pTable())); } else { TESTC(pColAccess->dwStatus == DBSTATUS_E_CANTCONVERTVALUE); } } CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(pData); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(34) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_34() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(35) //*----------------------------------------------------------------------- // @mfunc Boundary - bPrecision - make sure ignored on input for all types, except NUMERIC. // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_35() { // TO DO: Add your own code here return TRUE; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(36) //*----------------------------------------------------------------------- // @mfunc Boundary - bScale - make sure ignored on input for all types, except NUMERIC. // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_36() { // TO DO: Add your own code here return TRUE; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(37) //*----------------------------------------------------------------------- // @mfunc Boundary - Output Only - make sure cbDataLen, dwStatus, dwReserverd are ignored on input // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_37() { TBEGIN DBORDINAL i,cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; void* pData = NULL; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Create the ColAccess Structures (for all columns)... TESTC_(RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG),S_OK); //Loop through all columns for(i=0; idwStatus = DBSTATUS_S_OK + (ULONG)i + 1; //Everything beyond S_OK is interesting pColAccess->cbDataLen = (-1) - i; pColAccess->dwReserved = i; } //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColAccess, rgColAccess), S_OK); //Compare Data for this column TESTC(RowObjectA.CompareColAccess(cColAccess, rgColAccess, FIRST_ROW, pTable())); CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(pData); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(38) //*----------------------------------------------------------------------- // @mfunc Boundary - Input - Make sure all pointers and input args are not changed on output, pData pointer, columnid [including all union pointers], cbMaxLen, dwReserved, wType. // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_38() { TBEGIN DBORDINAL i,cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; DBCOLUMNACCESS* rgColAccessCopy = NULL; void* pData = NULL; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Create the ColAccess Structures (for all columns)... TESTC_(RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG),S_OK); //Make more interesting data for some of the items for(i=0; icolumnid, FALSE/*fDrop*/); pColAccess->columnid.eKind = (ULONG)i % (DBKIND_GUID+1); TESTC_(CreateUniqueDBID(&pColAccess->columnid),S_OK); } //The consumer might have used this reserver flag for internal storage, //so the provider should not be looking at it or setting it... pColAccess->dwReserved = i; } //Make a "snapshot" copy to compare against SAFE_ALLOC(rgColAccessCopy, DBCOLUMNACCESS, cColAccess); memcpy(rgColAccessCopy, rgColAccess, (size_t)(cColAccess*sizeof(DBCOLUMNACCESS))); //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColAccess, rgColAccess), cColAccess ? DB_S_ERRORSOCCURRED : S_OK); //Make more interesting data for some of the items for(i=0; icolumnid, &pColAccessCopy->columnid, sizeof(DBID))==0); TESTC(pColAccess->pData == pColAccessCopy->pData); TESTC(pColAccess->cbMaxLen == pColAccessCopy->cbMaxLen); TESTC(pColAccess->dwReserved == pColAccessCopy->dwReserved || pColAccess->dwReserved == 0); TESTC(pColAccess->wType == pColAccessCopy->wType); TESTC(pColAccess->bPrecision == pColAccessCopy->bPrecision); TESTC(pColAccess->bScale == pColAccessCopy->bScale); //Compare Data for this column if(i%2 == 0) { TESTC(pColAccess->dwStatus == DBSTATUS_E_DOESNOTEXIST); } else { TESTC(RowObjectA.CompareColAccess(1, pColAccess, FIRST_ROW, pTable())); } } CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(rgColAccessCopy); SAFE_FREE(pData); TRETURN } // }} TCW_VAR_PROTOTYPE_END BOOL TCIRow_GetColumns::FindColumnDBTYPE_BYTES(DBSTATUS status, DBCOUNTITEM *pRowIndex, DBORDINAL *pColIndex) { ASSERT(pRowIndex != NULL); ASSERT(pColIndex != NULL); DBORDINAL cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; void* pData = NULL; bool found = FALSE; DBCOUNTITEM rowCountInTable = m_pTable->GetRowsOnCTable(); for (DBCOUNTITEM rowIndex = 1; rowIndex < rowCountInTable; ++rowIndex) { //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(rowIndex, &RowObjectA), S_OK); //Create the ColAccess Structures (for all columns)... TESTC_(RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG),S_OK); //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColAccess, rgColAccess), S_OK); // column 0. non-null, improperly aligned for (DBORDINAL colIndex = 0; colIndex < cColAccess; ++colIndex) { if ((rgColAccess[colIndex].dwStatus == status) && (rgColAccess[colIndex].wType == DBTYPE_BYTES)) { *pRowIndex = rowIndex; *pColIndex = colIndex; found = TRUE; goto CLEANUP; } } FreeColAccess(cColAccess, rgColAccess); cColAccess = 0; rgColAccess = NULL; SAFE_FREE(pData); pData = NULL; } CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(pData); return found; } int TCIRow_GetColumns::UnalignedBuferTest(DBSTATUS columnStatus) { TBEGIN DBORDINAL cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; void* pData = NULL; BYTE* pDataUnaligned = NULL; CRowObject RowObjectA; DBCOUNTITEM rowIndex; DBORDINAL colIndex; BOOL found = FindColumnDBTYPE_BYTES(columnStatus, &rowIndex, &colIndex); if (!found) { TESTB = TEST_SKIPPED; goto CLEANUP; } TESTC_(GetRowObject(rowIndex, &RowObjectA), S_OK); TESTC_(RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG),S_OK); SAFE_ALLOC(pDataUnaligned, BYTE, rgColAccess[colIndex].cbMaxLen + 1); memset(pDataUnaligned, 0, (size_t)(rgColAccess[colIndex].cbMaxLen + 1)); rgColAccess[colIndex].pData = pDataUnaligned + 1; TESTC_(RowObjectA.GetColumns(cColAccess, rgColAccess), S_OK); ASSERT(rgColAccess[colIndex].dwStatus == columnStatus); CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(pData); SAFE_FREE(pDataUnaligned); TRETURN } // {{ TCW_VAR_PROTOTYPE(39) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_39() { //return UnalignedBuferTest(DBSTATUS_S_ISNULL);//Supply unaligned buffer for NULL bytes value return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(40) //*----------------------------------------------------------------------- // @mfunc Supply unaligned buffer for non-NULL bytes value // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_40() { return UnalignedBuferTest(DBSTATUS_S_OK); } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(41) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_41() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(42) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_42() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(43) //*----------------------------------------------------------------------- // @mfunc Buffered Mode - All Columns - no BLOBs // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_43() { 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(VerifyGetColumnsAllRows(&RowsetA, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(44) //*----------------------------------------------------------------------- // @mfunc Buffered Mode - All Columns - BLOBs // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_44() { 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(VerifyGetColumnsAllRows(&RowsetA, ALL_COLS_BOUND, BLOB_LONG)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(45) //*----------------------------------------------------------------------- // @mfunc Buffered Mode - All Columns - Just extra columns // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_45() { TBEGIN DBORDINAL cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; void* pData = NULL; DBORDINAL cColumns = 0; DBORDINAL* rgColOrdinals = NULL; HRESULT hr = E_FAIL; //Create a buffered mode rowset CRowsetUpdate RowsetA; CRowObject RowObjectA; //Not all providers will support IRowsetUpdate TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK); //Now create the row object. TESTC_(RowsetA.GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Obtain the just the Extra columns TEST2C_(hr = RowObjectA.GetExtraColumnInfo(&cColumns, NULL, NULL, &rgColOrdinals),S_OK,DB_E_NOSOURCEOBJECT); if(hr == DB_E_NOSOURCEOBJECT) { odtLog << "This provider does not support IRow::GetSourceRowset\n"; TESTB = TEST_SKIPPED; goto CLEANUP; } //Create the ColAccess Structures for just the extra columns... TESTC_(RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData, NULL, ALL_COLS_BOUND, BLOB_LONG, FORWARD, NO_COLS_BY_REF, DBTYPE_EMPTY, cColumns, rgColOrdinals),S_OK); //IRow::GetColumns TESTC_(RowObjectA.GetColumns(cColAccess, rgColAccess),S_OK); //Compare Data for this row object TESTC(RowObjectA.CompareColAccess(cColAccess, rgColAccess, FIRST_ROW, pTable())); CLEANUP: FreeColAccess(cColAccess, rgColAccess); SAFE_FREE(pData); SAFE_FREE(rgColOrdinals); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(46) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_46() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(47) //*----------------------------------------------------------------------- // @mfunc Aggregation - Command - > Row // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_47() { TBEGIN CAggregate Aggregate; IUnknown* pIUnkInner = NULL; ULONG_PTR dwValue = 0; HRESULT hr = S_OK; CCommand CommandA; CommandA.SetProperty(DBPROP_IRow); //Create a command object TESTC_PROVIDER(CommandA.CreateCommand()==S_OK); //Try the invalid senario first... (asking for non-IUnknown) TESTC_(hr = CommandA.SetCommandText(SELECT_ALLFROMTBL),S_OK); TESTC_(hr = CommandA.Execute(&Aggregate, IID_IRow, &pIUnkInner), DB_E_NOAGGREGATION); //Create a row object from IOpenRowset asking for IID_IRow. //But we are setting the DBPROP_IRow property, so the results is a row object not a rowset... TEST2C_(hr = CommandA.SetProperties(), S_OK, DB_E_ERRORSOCCURRED); if(SUCCEEDED(hr)) { TEST4C_(hr = CommandA.Execute(&Aggregate, IID_IUnknown, &pIUnkInner), S_OK, DB_S_NOTSINGLETON, DB_E_NOAGGREGATION, DB_E_ERRORSOCCURRED); Aggregate.SetUnkInner(pIUnkInner); } if(hr == DB_E_ERRORSOCCURRED) { //The only reason DB_E_ERRORSOCCURRED should be returned would be if the provider doesn't //support singleton row objects to be returned from OpenRowset or Execute. //NOTE: Sigleton objects are very useful, but none-the-less not required. //Verify the result with the advertised property value... TESTC(::GetProperty(DBPROP_OLEOBJECTS, DBPROPSET_DATASOURCEINFO, g_pIDBCreateSession, &dwValue)); TESTC(!(dwValue & DBPROPVAL_OO_SINGLETON)); } else { if(hr == DB_S_NOTSINGLETON) hr = S_OK; //Verify Aggregation for this row... TESTC_PROVIDER(Aggregate.VerifyAggregationQI(hr, IID_IRow)); } CLEANUP: SAFE_RELEASE(pIUnkInner); Aggregate.ReleaseInner(); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(48) //*----------------------------------------------------------------------- // @mfunc Aggregation - Session - > Row // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_48() { TBEGIN CAggregate Aggregate; IUnknown* pIUnkInner = NULL; ULONG_PTR dwValue = 0; HRESULT hr = S_OK; COpenRowset OpenRowsetA; OpenRowsetA.SetProperty(DBPROP_IRow); //Try the invalid senario first... (asking for non-IUnknown) TESTC_(hr = OpenRowsetA.CreateOpenRowset(IID_IRow, &pIUnkInner, &Aggregate, ROW_INTERFACE), DB_E_NOAGGREGATION); //Create a row object from IOpenRowset asking for IID_IRow. //But we are setting the DBPROP_IRow property, so the results is a row object not a rowset... OpenRowsetA.SetProperty(DBPROP_IRow); TEST4C_(hr = OpenRowsetA.CreateOpenRowset(IID_IUnknown, &pIUnkInner, &Aggregate, ROW_INTERFACE), S_OK, DB_S_NOTSINGLETON, DB_E_NOAGGREGATION, DB_E_ERRORSOCCURRED); Aggregate.SetUnkInner(pIUnkInner); if(hr == DB_E_ERRORSOCCURRED) { //The only reason DB_E_ERRORSOCCURRED should be returned would be if the provider doesn't //support singleton row objects to be returned from OpenRowset or Execute. //NOTE: Sigleton objects are very useful, but none-the-less not required. //Verify the result with the advertised property value... TESTC(::GetProperty(DBPROP_OLEOBJECTS, DBPROPSET_DATASOURCEINFO, g_pIDBCreateSession, &dwValue)); TESTC(!(dwValue & DBPROPVAL_OO_SINGLETON)); } else { if(hr == DB_S_NOTSINGLETON) hr = S_OK; //Verify Aggregation for this row... TESTC_PROVIDER(Aggregate.VerifyAggregationQI(hr, IID_IRow)); } CLEANUP: SAFE_RELEASE(pIUnkInner); Aggregate.ReleaseInner(); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(49) //*----------------------------------------------------------------------- // @mfunc Aggregation - Rowset -> Row // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_49() { TBEGIN HROW hRow = NULL; CAggregate Aggregate; IUnknown* pIUnkInner = NULL; CRowset RowsetA; HRESULT hr = S_OK; //Create a rowset TESTC_(RowsetA.CreateRowset(),S_OK) //Obtain the second row object (aggregated) hr = RowsetA.GetRowObject(&Aggregate, FIRST_ROW, IID_IUnknown, &pIUnkInner); Aggregate.SetUnkInner(pIUnkInner); //Verify Aggregation... TESTC_PROVIDER(Aggregate.VerifyAggregationQI(hr, IID_IRow)); CLEANUP: RowsetA.ReleaseRows(hRow); SAFE_RELEASE(pIUnkInner); Aggregate.ReleaseInner(); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(50) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_50() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(51) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_51() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(52) //*----------------------------------------------------------------------- // @mfunc Properties - DBPROP_IRow // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_52() { TBEGIN IUnknown* pIUnknown = NULL; HRESULT hr = S_OK; ULONG i; //Make sure the required Row Object properties (including DBPROP_IRow) are supported for(i=0; idwPropertyID) { //Make sure this property is supported. if(SupportedProperty(pMap->dwPropertyID, DBPROPSET_ROWSET)) { //See is this interface is available TEST2C_(hr = m_pCRowObject->pIRow()->QueryInterface(*pMap->pIID, (void**)&pIUnknown), S_OK, E_NOINTERFACE); if(SUCCEEDED(hr)) { TESTC(DefaultObjectTesting(pIUnknown, ROW_INTERFACE)); SAFE_RELEASE(pIUnknown); } else { //Make sure this is not one of the mandatory interfaces //All of the mandotry interfaces must be supported if(pMap->fMandatory) TERROR(L"Mandatory Property not supported " << pMap->pwszName); } } else { //Make sure this is not one of the mandatory properties. //All of the mandotry properties must be supported if(pMap->fMandatory) TERROR(L"Mandatory Property not supported " << pMap->pwszName); //Make sure this interface is not supported, since the property is not if(E_NOINTERFACE != m_pCRowObject->pIRow()->QueryInterface(*pMap->pIID, (void**)&pIUnknown)) TERROR(L"Interface available although property failed for " << GetInterfaceName(*pMap->pIID)); } } } CLEANUP: SAFE_RELEASE(pIUnknown); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(53) //*----------------------------------------------------------------------- // @mfunc Properties - DBPROP_OLEOBJECTS - DBPROPVAL_OO_ROWOBJECT // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_53() { TBEGIN ULONG_PTR dwObjects = 0; CRowset RowsetA; CRowObject RowObjectA; TESTC_(RowsetA.CreateRowset(),S_OK); //If we have made it pass ModuleInit, then the provider supports Row Objects //So make sure they also advertise they support row objects through the property. //Required for early bound applications, vs. runtime applications TESTC(::GetProperty(DBPROP_OLEOBJECTS, DBPROPSET_DATASOURCEINFO, g_pIDBCreateSession, &dwObjects)); TESTC(BITSET(dwObjects, DBPROPVAL_OO_ROWOBJECT) || BITSET(dwObjects, DBPROPVAL_OO_SINGLETON)); //Make sure the property only contains valid flags TESTC(!(dwObjects & ~(DBPROPVAL_OO_BLOB | DBPROPVAL_OO_IPERSIST | DBPROPVAL_OO_DIRECTBIND | DBPROPVAL_OO_ROWOBJECT | DBPROPVAL_OO_SCOPED | DBPROPVAL_OO_SINGLETON))); //Now make sure the property was correctly represents whats supported... TESTC_(RowsetA.GetRowObject(FIRST_ROW, &RowObjectA, DBPROPVAL_OO_SINGLETON), dwObjects & DBPROPVAL_OO_SINGLETON ? S_OK : E_NOINTERFACE); TESTC_(RowsetA.GetRowObject(FIRST_ROW, &RowObjectA, DBPROPVAL_OO_ROWOBJECT), dwObjects & DBPROPVAL_OO_ROWOBJECT ? S_OK : E_NOINTERFACE); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(54) //*----------------------------------------------------------------------- // @mfunc Properties - DBPROP_OLEOBJECTS - DBPROPVAL_OO_SINGLETON // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_54() { TBEGIN CRowset RowsetA; IUnknown* pIUnknown = NULL; ULONG_PTR dwValue = 0; ULONG cPropSets = 0; DBPROPSET* rgPropSets = NULL; ::SetProperty(DBPROP_IRow, DBPROPSET_ROWSET, &cPropSets, &rgPropSets); //NOTE: Sigleton objects are very useful, but none-the-less not required. //Verify the result with the advertised property value... if(::GetProperty(DBPROP_OLEOBJECTS, DBPROPSET_DATASOURCEINFO, g_pIDBCreateSession, &dwValue) && dwValue & DBPROPVAL_OO_SINGLETON) { //Create a row object from ICommand::Execute asking for IID_IRow TEST2C_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRow, 0, NULL, &pIUnknown), S_OK, DB_S_NOTSINGLETON); TESTC(DefaultObjectTesting(pIUnknown, ROW_INTERFACE)); SAFE_RELEASE(pIUnknown); //Create a row object from IOpenRowset asking for IID_IRown. //But we are setting the DBPROP_IRow property, so the results is a row object not a rowset... TEST2C_(RowsetA.pTable()->CreateRowset(USE_OPENROWSET, IID_IRow, 0, NULL, &pIUnknown), S_OK, DB_S_NOTSINGLETON); TESTC(DefaultObjectTesting(pIUnknown, ROW_INTERFACE)); SAFE_RELEASE(pIUnknown); //Create a row object from ICommand::Execute asking for IID_IUnknown. //But we are setting the DBPROP_IRow property, so the results is a row object not a rowset... TEST2C_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IUnknown, cPropSets, rgPropSets, &pIUnknown),S_OK,DB_S_NOTSINGLETON); TESTC(DefaultObjectTesting(pIUnknown, ROW_INTERFACE)); SAFE_RELEASE(pIUnknown); //Create a row object from IOpenRowset asking for IID_IRown. //But we are setting the DBPROP_IRow property, so the results is a row object not a rowset... TEST2C_(RowsetA.pTable()->CreateRowset(USE_OPENROWSET, IID_IUnknown, cPropSets, rgPropSets, &pIUnknown), S_OK, DB_S_NOTSINGLETON); TESTC(DefaultObjectTesting(pIUnknown, ROW_INTERFACE)); SAFE_RELEASE(pIUnknown); } else { TESTC_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IRow, 0, NULL, &pIUnknown),E_NOINTERFACE); TESTC_(RowsetA.pTable()->CreateRowset(USE_OPENROWSET, IID_IRow, 0, NULL, &pIUnknown),E_NOINTERFACE); TESTC_(RowsetA.pTable()->CreateRowset(SELECT_ALLFROMTBL, IID_IUnknown, cPropSets, rgPropSets, &pIUnknown),E_NOINTERFACE); TESTC_(RowsetA.pTable()->CreateRowset(USE_OPENROWSET, IID_IUnknown, cPropSets, rgPropSets, &pIUnknown),E_NOINTERFACE); } CLEANUP: SAFE_RELEASE(pIUnknown); ::FreeProperties(&cPropSets, &rgPropSets); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(55) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_55() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(56) //*----------------------------------------------------------------------- // @mfunc Properties - All Row Object Properties // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_56() { TBEGIN CRowset RowsetA; IUnknown* pIUnknown = NULL; IUnknown* pIUnknown2 = NULL; ULONG cPropSets = 0; DBPROPSET* rgPropSets = NULL; HRESULT hr = S_OK; ULONG i; //Set all Row Object Properties (REQUIRED) for(i=0; idwPropertyID) ::SetProperty(pMap->dwPropertyID, DBPROPSET_ROWSET, &cPropSets, &rgPropSets); } //OpenRowset TEST3C_(hr = RowsetA.pTable()->CreateRowset(USE_OPENROWSET, IID_IUnknown, cPropSets, rgPropSets, &pIUnknown),S_OK,DB_S_NOTSINGLETON,DB_E_ERRORSOCCURRED); //Verify a Row object is returned... if(pIUnknown) TESTC(DefaultObjectTesting(pIUnknown, ROW_INTERFACE)); //Verify returned Properties... for(i=0; idwPropertyID) { DBPROP* pProp = NULL; TESTC(FindProperty(pMap->dwPropertyID, DBPROPSET_ROWSET, cPropSets, rgPropSets, &pProp)); //If the property succeeded, then the interface must be available. //(ie: provider can always return extra functionalty, but must at least the mininal asked for) if(pProp->dwStatus == DBPROPSTATUS_OK) { if(SUCCEEDED(hr)) { //Then all the properties must have succeeded TESTC(VerifyPropSetStatus(cPropSets, rgPropSets, DBPROPSTATUS_OK)); //Make sure the interface is available if(S_OK != pIUnknown->QueryInterface(*pMap->pIID, (void**)&pIUnknown2)) TERROR(L"Interface not available although property succeeded for " << GetInterfaceName(*pMap->pIID)); TESTC(DefaultObjectTesting(pIUnknown2, ROW_INTERFACE)); SAFE_RELEASE(pIUnknown2); } } else { //Some providers still don't met the spec and fail DBPROP_I*, //since the property DBPROP_I* was set and the interface IID_I* was not asked //for. This is wrong, and against the spec, which states that asking for //DBPROP_I* is just like implicilty asking for IID_I*. Test it here, //to make sure the provider truely doesn't support this interface, //so we don't skip them incorrectly //The mandatory properties cannot fail... if(pMap->fMandatory) TERROR(L"Mandatory Property failed for " << pMap->pwszName << "\n"); //Optional properties can be not supported. //NOTE: Some optional row object properties may not be supported on the row object //even though they are supported on the rowset. (ie: IConnectionPointContainer). TESTC(pProp->dwStatus == DBPROPSTATUS_NOTSUPPORTED || pProp->dwStatus == DBPROPSTATUS_CONFLICTING); //Make sure the interface is not available if(SUCCEEDED(hr)) { TESTC_(pIUnknown->QueryInterface(*pMap->pIID, (void**)&pIUnknown2), E_NOINTERFACE); } //Make sure asking for the IID also fails... //NOTE: We have to set the DBPROP_IRow for some cases... ULONG cRowProp = 0; DBPROPSET* rgRowProp = NULL; if(!(*pMap->pIID == IID_IRow || *pMap->pIID == IID_IRowChange || *pMap->pIID == IID_IRowSchemaChange)) ::SetProperty(DBPROP_IRow, DBPROPSET_ROWSET, &cRowProp, &rgRowProp); if(RowsetA.pTable()->CreateRowset(USE_OPENROWSET, *pMap->pIID, cRowProp, rgRowProp, &pIUnknown)!=E_NOINTERFACE) TERROR(L"Property Incorrect for " << GetPropertyName(pMap->dwPropertyID, DBPROPSET_ROWSET) << "\n"); ::FreeProperties(&cRowProp, &rgRowProp); } } } CLEANUP: SAFE_RELEASE(pIUnknown); SAFE_RELEASE(pIUnknown2); ::FreeProperties(&cPropSets, &rgPropSets); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(57) //*----------------------------------------------------------------------- // @mfunc Properties - All Row Object Properties Optional // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_57() { TBEGIN CRowset RowsetA; IUnknown* pIUnknown = NULL; IUnknown* pIUnknown2 = NULL; HRESULT hr = S_OK; ULONG cPropSets = 0; DBPROPSET* rgPropSets = NULL; ULONG i; //Set all Row Object Properties (Mandatory-REQUIRED, Optional-OPTIONAL) for(i=0; idwPropertyID) ::SetProperty(pMap->dwPropertyID, DBPROPSET_ROWSET, &cPropSets, &rgPropSets, (void*)VARIANT_TRUE, DBTYPE_BOOL, pMap->fMandatory ? DBPROPOPTIONS_REQUIRED : DBPROPOPTIONS_OPTIONAL); } //OpenRowset TEST3C_(hr = RowsetA.pTable()->CreateRowset(USE_OPENROWSET, IID_IUnknown, cPropSets, rgPropSets, &pIUnknown),S_OK,DB_S_NOTSINGLETON,DB_S_ERRORSOCCURRED); //Verify a Row object is returned... TESTC(DefaultObjectTesting(pIUnknown, ROW_INTERFACE)); //Verify returned Properties... for(i=0; idwPropertyID) TCOMPARE_(VerifyPropStatus(cPropSets, rgPropSets, pMap->dwPropertyID, DBPROPSET_ROWSET, DBPROPSTATUS_OK)); } //NOTE: The spec indicates that DB_S_ERRORSOCCURRED, superceeds DB_S_NOTSINGLETON. //So if there are any property errors then DB_S_ERRORSOCCURRED is returned. DB_S_NOTSINGLETON //will only be returned in the case that no property errors... if(hr == DB_S_NOTSINGLETON) { //Then all the properties must have succeeded TESTC(VerifyPropSetStatus(cPropSets, rgPropSets, DBPROPSTATUS_OK)); } //For all properties that did succeed, the interface should be available... for(i=0; idwPropertyID) { DBPROP* pProp = NULL; TESTC(FindProperty(pMap->dwPropertyID, DBPROPSET_ROWSET, cPropSets, rgPropSets, &pProp)); //If the property succeeded, then the interface must be available. //(ie: provider can always return extra functionalty, but must at least the mininal asked for) if(pProp->dwStatus == DBPROPSTATUS_OK) { if(SUCCEEDED(hr)) { if(S_OK != pIUnknown->QueryInterface(*pMap->pIID, (void**)&pIUnknown2)) TERROR(L"Interface not available although property succeeded for " << GetInterfaceName(*pMap->pIID)); TESTC(DefaultObjectTesting(pIUnknown2, ROW_INTERFACE)); SAFE_RELEASE(pIUnknown2); } } else { //Some providers still don't met the spec and fail DBPROP_I*, //since the property DBPROP_I* was set and the interface IID_I* was not asked //for. This is wrong, and against the spec, which states that asking for //DBPROP_I* is just like implicilty asking for IID_I*. Test it here, //to make sure the provider truely doesn't support this interface, //so we don't skip them incorrectly //The mandatory properties cannot fail... TESTC(!pMap->fMandatory); if(SUCCEEDED(hr)) { //Make sure the interface is not available TESTC_(pIUnknown->QueryInterface(*pMap->pIID, (void**)&pIUnknown2), E_NOINTERFACE); } //Make sure asking for the IID also fails... //NOTE: We have to set the DBPROP_IRow for some cases... ULONG cRowProp = 0; DBPROPSET* rgRowProp = NULL; if(!(*pMap->pIID == IID_IRow || *pMap->pIID == IID_IRowChange || *pMap->pIID == IID_IRowSchemaChange)) ::SetProperty(DBPROP_IRow, DBPROPSET_ROWSET, &cRowProp, &rgRowProp); if(RowsetA.pTable()->CreateRowset(USE_OPENROWSET, *pMap->pIID, cRowProp, rgRowProp, &pIUnknown2)!=E_NOINTERFACE) TERROR(L"Property Incorrect for " << GetPropertyName(pMap->dwPropertyID, DBPROPSET_ROWSET) << "\n"); ::FreeProperties(&cRowProp, &rgRowProp); } } } CLEANUP: SAFE_RELEASE(pIUnknown); SAFE_RELEASE(pIUnknown2); ::FreeProperties(&cPropSets, &rgPropSets); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(58) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_58() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(59) //*----------------------------------------------------------------------- // @mfunc Properties - Rowset Properties // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_59() { TBEGIN CRowset RowsetA; CRowObject RowObjectA; ULONG_PTR dwValue = 0; ULONG cPropSets = 0; DBPROPSET* rgPropSets = NULL; IRow* pIRow = NULL; //This variation require Singleton row objects. To test different properties on the row object. TESTC_PROVIDER(::GetProperty(DBPROP_OLEOBJECTS, DBPROPSET_DATASOURCEINFO, g_pIDBCreateSession, &dwValue) && dwValue & DBPROPVAL_OO_SINGLETON); //Set some interesting Rowset properties, to make sure their ignored (or correctly looked at) on the row object... //TODO: We need to improve GetRowObject to set more than just AccessOrder, so all our rowset //proopery scenarios are already covered. For now just do a good combination of rowset properties. ::SetSettableProperty(DBPROP_ACCESSORDER, DBPROPSET_ROWSET, &cPropSets, &rgPropSets, (void*)DBPROPVAL_AO_RANDOM, DBTYPE_I4); // ::SetSettableProperty(DBPROP_OTHERUPDATEDELETE, DBPROPSET_ROWSET, &cPropSets, &rgPropSets); // ::SetSettableProperty(DBPROP_UNIQUEROWS, DBPROPSET_ROWSET, &cPropSets, &rgPropSets); //Create a row object from ICommand::Execute asking for IID_IRow TEST2C_(RowsetA.pTable()->CreateRowset(SELECT_ORDERBYNUMERIC, IID_IRow, cPropSets, rgPropSets, (IUnknown**)&pIRow), S_OK, DB_S_NOTSINGLETON); RowObjectA.SetRowObject(pIRow); //Verify the Row object returned... TESTC(RowObjectA.VerifyGetColumns(FIRST_ROW, RowsetA.pTable(), ALL_COLS_BOUND)); TESTC(RowObjectA.VerifyGetColumns(FIRST_ROW, RowsetA.pTable(), ALL_COLS_BOUND)); CLEANUP: SAFE_RELEASE(pIRow); ::FreeProperties(&cPropSets, &rgPropSets); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(60) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_60() { // TO DO: Add your own code here return TRUE; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(61) //*----------------------------------------------------------------------- // @mfunc Threads - GetColumns seperate threads // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_61() { TBEGIN INIT_THREADS(MAX_THREADS); //Setup Thread Arguments THREADARG T1Arg = { this, m_pCRowObject }; //Create Threads CREATE_THREADS(Thread_VerifyGetColumns, &T1Arg); START_THREADS(); END_THREADS(); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(62) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_62() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(63) //*----------------------------------------------------------------------- // @mfunc Boundary - DB_E_DELETEDROW // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_63() { TBEGIN DBCOUNTITEM cRowsObtained = 0; HROW* rghRows = NULL; HROW hLastRow = NULL; CRowsetChange RowsetA; CRowObject RowObjectA; HRESULT hr = S_OK; //Create a new rowset //Provider must support IRowsetChange TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK); //Obtain the last row handle //We could just do (-1, 1) or (0, -1) but that would require fetching backwards... TEST3C_(hr = RowsetA.GetNextRows(0, 1000, &cRowsObtained, &rghRows), S_OK, DB_S_ENDOFROWSET, DB_S_ROWLIMITEXCEEDED); TESTC(cRowsObtained && rghRows); hLastRow = rghRows[cRowsObtained - 1]; //Now create the row object. TEST3C_(hr=RowObjectA.CreateRowObject(RowsetA.pIRowset(), hLastRow), S_OK, DB_S_NOROWSPECIFICCOLUMNS,E_NOINTERFACE); if(hr == E_NOINTERFACE) { odtLog << "This provider does not support IGetRow interface\n"; TESTB = TEST_SKIPPED; goto CLEANUP; } //While the row object is open, delete the row out from under it... //NOTE: The other senario, deleting the row handle before creating //the row object is done in the IGetRow test TESTC_(RowsetA.DeleteRow(hLastRow),S_OK); RowsetA.pTable()->SubtractRow(); //Now try and use the row object TESTC_(RowObjectA.GetColumns(RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess), DB_E_DELETEDROW); CLEANUP: RowsetA.ReleaseRows(cRowsObtained, rghRows); PROVIDER_FREE(rghRows); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(64) //*----------------------------------------------------------------------- // @mfunc Boundary - DB_E_DELETEDROW - Bufferred Mode // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetColumns::Variation_64() { TBEGIN HROW hRow = NULL; CRowsetUpdate RowsetA; CRowObject RowObjectA; HRESULT hr = E_FAIL; //Create a new rowset //Provider must support IRowsetUpdate TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK); //Obtain the first row handle TESTC_(RowsetA.GetNextRows(&hRow),S_OK); //Now create the row object. TEST3C_(hr = RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow), S_OK, DB_S_NOROWSPECIFICCOLUMNS,E_NOINTERFACE); if(hr == E_NOINTERFACE) { odtLog << "This provider does not support IGetRow interface\n"; TESTB = TEST_SKIPPED; goto CLEANUP; } //While the row object is open, delete the row out from under it... //NOTE: The other senario, deleting the row handle before creating //the row object is done in the IGetRow test TESTC_(RowsetA.DeleteRow(hRow),S_OK); //Now try and use the row object TESTC_(RowObjectA.GetColumns(RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess), DB_E_DELETEDROW); //Actually Update the backend TESTC_(RowsetA.UpdateRow(hRow),S_OK); RowsetA.pTable()->SubtractRow(); TESTC_(RowObjectA.GetColumns(RowObjectA.m_cColAccess, RowObjectA.m_rgColAccess), DB_E_DELETEDROW); CLEANUP: RowsetA.ReleaseRows(hRow); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_TERMINATE_METHOD //*----------------------------------------------------------------------- // @mfunc TestCase Termination Routine // // @rdesc TEST_PASS or TEST_FAIL // BOOL TCIRow_GetColumns::Terminate() { // {{ TCW_TERM_BASECLASS_CHECK2 return(TCIRow::Terminate()); } // }} // }} TCW_TERMINATE_METHOD_END // }} TCW_TC_PROTOTYPE_END // {{ TCW_TC_PROTOTYPE(TCIRow_GetSourceRowset) //*----------------------------------------------------------------------- //| Test Case: TCIRow_GetSourceRowset - IRow::GetSourceRowset //| Created: 8/5/98 //*----------------------------------------------------------------------- //*----------------------------------------------------------------------- // @mfunc TestCase Initialization Routine // // @rdesc TRUE or FALSE // BOOL TCIRow_GetSourceRowset::Init() { // {{ TCW_INIT_BASECLASS_CHECK if(TCIRow::Init()) // }} { return TRUE; } return FALSE; } // {{ TCW_VAR_PROTOTYPE(1) //*----------------------------------------------------------------------- // @mfunc riid - All Mandatory interfaces // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_1() { TBEGIN HRESULT hr = S_OK; IUnknown* pIUnknown = NULL; ULONG i; //Obtain the Rowset interfaces... ULONG cRowsetIIDs = 0; INTERFACEMAP* rgRowsetIIDs = NULL; GetInterfaceArray(ROWSET_INTERFACE, &cRowsetIIDs, &rgRowsetIIDs); //For every [MANDATORY] interface, try to object the parent rowset object... for(i=0; iGetSourceRowset(*rgRowsetIIDs[i].pIID, (IUnknown**)&pIUnknown, NULL); if(hr==DB_E_NOSOURCEOBJECT) TWARNING(L"Unable to obtain parent object?"); //Determine results if(rgRowsetIIDs[i].fMandatory) { //[MANDATORY] if(hr!=S_OK && hr!=DB_E_NOSOURCEOBJECT) { CHECK(hr, S_OK); TOUTPUT_(L"ERROR: Interface Incorrect for " << GetInterfaceName(*rgRowsetIIDs[i].pIID) << "\n"); } } else { //[OPTIONAL] if(hr!=S_OK && hr!=DB_E_NOSOURCEOBJECT && hr!=E_NOINTERFACE) { CHECK(hr, S_OK); TOUTPUT_(L"ERROR: Interface Incorrect for " << GetInterfaceName(*rgRowsetIIDs[i].pIID) << "\n"); } } SAFE_RELEASE(pIUnknown); } SAFE_RELEASE(pIUnknown); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(2) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_2() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(3) //*----------------------------------------------------------------------- // @mfunc Optional Args - [any riid, NULL, NULL] - S_OK // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_3() { TBEGIN //Get the Original Reference count... ULONG ulOrgRefCount = GetRefCount(pIRowset()); //IRow::GetSourceRowset //NOTE: The spec doesn't inforce order of error processing. So if a provider is able to determine //they don't have a source object, (before) determining there are no output params, we have //to allow for both errors. TEST2C_(m_pCRowObject->GetSourceRowset(IID_IUnknown, NULL, NULL), E_INVALIDARG, DB_E_NOSOURCEOBJECT); //Make sure the refcount was not incresed since we don't have a pointer to release... TESTC(ulOrgRefCount == GetRefCount(pIRowset())); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(4) //*----------------------------------------------------------------------- // @mfunc Optional Args - [any riid, NULL, valid] - S_OK with hRow // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_4() { TBEGIN HROW hRow = NULL; HRESULT hr = S_OK; //IRow::GetSourceRowset TEST2C_(hr = m_pCRowObject->GetSourceRowset(IID_IUnknown, NULL, &hRow),S_OK,DB_E_NOSOURCEOBJECT); //Verify this row handle... if(SUCCEEDED(hr)) { TESTC(VerifyRowHandles(hRow, FIRST_ROW)); } CLEANUP: ReleaseRows(hRow); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(5) //*----------------------------------------------------------------------- // @mfunc Optional Args - [IID_IUnknown, valid, NULL] - S_OK with Rowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_5() { TBEGIN IUnknown* pIUnknown = NULL; HRESULT hr = S_OK; //IRow::GetSourceRowset TEST2C_(hr = m_pCRowObject->GetSourceRowset(IID_IUnknown, &pIUnknown, NULL),S_OK,DB_E_NOSOURCEOBJECT); //Verify the rowset returned... if(SUCCEEDED(hr)) { //NOTE: This is already done in the GetSourceRowset helper, but just for completeness... TESTC(DefaultObjectTesting(pIUnknown, ROWSET_INTERFACE)); } CLEANUP: SAFE_RELEASE(pIUnknown); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(6) //*----------------------------------------------------------------------- // @mfunc Optional Args - [IID_IRowset, valid, valid] - S_OK with Rowset and hRow // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_6() { TBEGIN IUnknown* pIUnknown = NULL; HROW hRow = NULL; HRESULT hr = S_OK; //IRow::GetSourceRowset TEST2C_(hr = m_pCRowObject->GetSourceRowset(IID_IUnknown, &pIUnknown, &hRow),S_OK,DB_E_NOSOURCEOBJECT); if(SUCCEEDED(hr)) { //Verify the rowset returned... TESTC(DefaultObjectTesting(pIUnknown, ROWSET_INTERFACE)); //Verify this row handle... TESTC(VerifyRowHandles(hRow, FIRST_ROW)); } CLEANUP: ReleaseRows(hRow); SAFE_RELEASE(pIUnknown); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(7) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_7() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(8) //*----------------------------------------------------------------------- // @mfunc Sequence - Execute -> Row -> GetSourceRowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_8() { TBEGIN CRowset RowsetA; CRowObject RowObjectA; IRow* pIRow = NULL; IUnknown* pIUnknown = NULL; //Create a row object from ICommand::Execute TEST2C_(RowsetA.pTable()->CreateRowset(SELECT_ORDERBYNUMERIC, IID_IRow, 0, NULL, (IUnknown**)&pIRow),S_OK,DB_S_NOTSINGLETON); //Verify the Row object returned... TESTC_(RowObjectA.SetRowObject(pIRow),S_OK); TESTC(RowObjectA.VerifyGetColumns(FIRST_ROW, RowsetA.pTable(), ALL_COLS_BOUND)); //Try to get back top the creating rowset object... TEST2C_(RowObjectA.GetSourceRowset(IID_IUnknown, &pIUnknown, NULL), S_OK, DB_E_NOSOURCEOBJECT); CLEANUP: SAFE_RELEASE(pIRow); SAFE_RELEASE(pIUnknown); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(9) //*----------------------------------------------------------------------- // @mfunc Sequence - Execute -> Rowset -> Row -> GetSourceRowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_9() { TBEGIN CRowset RowsetA; CRowObject RowObjectA; IUnknown* pIUnknown = NULL; HROW hRow = NULL; HRESULT hr = S_OK; //Create a rowset from ICommand::Execute TESTC_PROVIDER(m_ulpOleObjects & DBPROPVAL_OO_ROWOBJECT); TESTC_(RowsetA.CreateRowset(SELECT_ORDERBYNUMERIC),S_OK); //Create the Row Object from the rowset... TESTC_(RowsetA.GetNextRows(&hRow),S_OK); TEST2C_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow), S_OK, DB_S_NOROWSPECIFICCOLUMNS); TESTC(RowObjectA.VerifyGetColumns(FIRST_ROW, RowsetA.pTable(), ALL_COLS_BOUND)); //Try to get back top the creating rowset object... TEST2C_(hr = RowObjectA.GetSourceRowset(IID_IUnknown, &pIUnknown, NULL), S_OK, DB_E_NOSOURCEOBJECT); if(SUCCEEDED(hr)) { VerifyEqualInterface(pIUnknown, RowsetA.pIRowset()); } CLEANUP: SAFE_RELEASE(pIUnknown); RowsetA.ReleaseRows(hRow); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(10) //*----------------------------------------------------------------------- // @mfunc Sequence - OpenRowset -> Row -> Release Rowset -> GetSourceRowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_10() { TBEGIN CRowset RowsetA; CRowObject RowObjectA; IRow* pIRow = NULL; IUnknown* pIUnknown = NULL; //Create a row object from IOpenRowset TEST2C_(RowsetA.pTable()->CreateRowset(USE_OPENROWSET, IID_IRow, 0, NULL, (IUnknown**)&pIRow),S_OK,DB_S_NOTSINGLETON); //Verify the Row object returned... TESTC_(RowObjectA.SetRowObject(pIRow),S_OK); TESTC(RowObjectA.VerifyGetColumns(FIRST_ROW, RowsetA.pTable(), ALL_COLS_BOUND)); //Try to get back top the creating rowset object... TEST2C_(RowObjectA.GetSourceRowset(IID_IUnknown, &pIUnknown, NULL), S_OK, DB_E_NOSOURCEOBJECT); CLEANUP: SAFE_RELEASE(pIRow); SAFE_RELEASE(pIUnknown); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(11) //*----------------------------------------------------------------------- // @mfunc Sequence - OpenRowset -> Rowset -> Row -> Release Rowset -> GetSourceRowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_11() { TBEGIN CRowset RowsetA; CRowObject RowObjectA; IUnknown* pIUnknown = NULL; HROW hRow = NULL; HRESULT hr = S_OK; //Create a rowset from IOpenRowset TESTC_PROVIDER(m_ulpOleObjects & DBPROPVAL_OO_ROWOBJECT); TESTC_(RowsetA.CreateRowset(USE_OPENROWSET),S_OK); //Create the Row Object from the rowset... TESTC_(RowsetA.GetNextRows(2, ONE_ROW, &hRow),S_OK); TEST2C_(RowObjectA.CreateRowObject(RowsetA.pIRowset(), hRow), S_OK, DB_S_NOROWSPECIFICCOLUMNS); TESTC(RowObjectA.VerifyGetColumns(THIRD_ROW, RowsetA.pTable(), ALL_COLS_BOUND)); //Release the Rowset. TESTC_(RowsetA.ReleaseRows(hRow),S_OK); RowsetA.DropRowset(); //Try to get back top the creating rowset object... TEST2C_(RowObjectA.GetSourceRowset(IID_IUnknown, &pIUnknown, &hRow), S_OK, DB_E_NOSOURCEOBJECT); //Verify the row handle returned... TESTC_(RowsetA.CreateRowset(pIUnknown),S_OK); TESTC(RowsetA.VerifyRowHandles(ONE_ROW, &hRow, THIRD_ROW)); TESTC_(RowsetA.ReleaseRows(hRow),S_OK); //The Rowset returned from GetSourceRowset, usally jsut returns the Rowset with a NFP //in the same place. But since the user has completley released their refcounts, the rowset //may or may not still be alive by the providers implementation. If they internally keep a reference //on it for the row, then the NFP will basically be where we left off, if not then it will //be at the start of the rowset. RowObjectA.ReleaseRowObject(); TESTC_(RowsetA.GetNextRows(&hRow),S_OK); TESTC(RowsetA.VerifyRowHandles(ONE_ROW, &hRow, FOURTH_ROW) || RowsetA.VerifyRowHandles(ONE_ROW, &hRow, FIRST_ROW)); CLEANUP: SAFE_RELEASE(pIUnknown); RowsetA.ReleaseRows(hRow); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(12) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_12() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(13) //*----------------------------------------------------------------------- // @mfunc Multiple - GetSourceRowset from numerous child row objects // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_13() { TBEGIN CRowset RowsetA; IUnknown* pIUnknown = NULL; HRESULT hr = S_OK; CRowObject** rgpCRowObjects = NULL; DBCOUNTITEM iRow, cRowsObtained = 0; HROW* rghRows = NULL; //Create a rowset from IOpenRowset TESTC_PROVIDER(m_ulpOleObjects & DBPROPVAL_OO_ROWOBJECT); TESTC_(RowsetA.CreateRowset(DBPROP_CANHOLDROWS),S_OK); //Grab as many rows as possible... TEST3C_(RowsetA.GetNextRows(0, 1000, &cRowsObtained, &rghRows), S_OK, DB_S_ENDOFROWSET, DB_S_ROWLIMITEXCEEDED); //Create the Row Objects from the rowset, (leave active) SAFE_ALLOC(rgpCRowObjects, CRowObject*, cRowsObtained); memset(rgpCRowObjects, 0, (size_t)(cRowsObtained * sizeof(CRowObject*))); //Loop over all the rows Obtained for(iRow=0; iRowGetSourceRowset(IID_IUnknown, &pIUnknown, NULL), S_OK, DB_E_NOSOURCEOBJECT); if(pIUnknown) { //Make sure its returning the original object TESTC(VerifyEqualInterface(pIUnknown, RowsetA.pIRowset())); } SAFE_RELEASE(pIUnknown); } CLEANUP: for(iRow=0; iRow Agg Row -> GetSourceRowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_16() { TBEGIN HROW hRow = NULL; CAggregate Aggregate(pIRowset()); IUnknown* pIAggregate = NULL; IGetRow* pIGetRow = NULL; IRow* pIRow = NULL; IUnknown* pIUnkInner = NULL; HRESULT hr = S_OK; CRowset RowsetA; CRowObject RowObjectA; //Obtain the second row TESTC_PROVIDER(m_ulpOleObjects & DBPROPVAL_OO_ROWOBJECT); TESTC_(RowsetA.CreateRowset(),S_OK); TESTC_(RowsetA.GetRow(SECOND_ROW, &hRow),S_OK); //Obtain a row object... hr = RowsetA.GetRowFromHROW(&Aggregate, hRow, IID_IUnknown, (IUnknown**)&pIUnkInner); Aggregate.SetUnkInner(pIUnkInner); //Verify Aggregation for this row... TESTC_PROVIDER(Aggregate.VerifyAggregationQI(hr, IID_IRow, (IUnknown**)&pIRow)); TESTC_(RowObjectA.SetRowObject(pIRow),S_OK); //IRow::GetSourceRowset TEST2C_( hr = RowObjectA.GetSourceRowset(IID_IAggregate, (IUnknown**)&pIAggregate, NULL),E_NOINTERFACE, DB_E_NOSOURCEOBJECT); TEST2C_(hr = RowObjectA.GetSourceRowset(IID_IGetRow, (IUnknown**)&pIGetRow, NULL), S_OK, DB_E_NOSOURCEOBJECT); if(hr==S_OK) { TESTC(VerifyEqualInterface(RowsetA.pIRowset(), pIGetRow)); } else { TWARNING(L"IRow::GetSourceRowset unable to retrieve Parent object!"); } CLEANUP: RowsetA.ReleaseRows(hRow); SAFE_RELEASE(pIAggregate); SAFE_RELEASE(pIGetRow); SAFE_RELEASE(pIRow); SAFE_RELEASE(pIUnkInner); RowObjectA.ReleaseRowObject(); Aggregate.ReleaseInner(); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(17) //*----------------------------------------------------------------------- // @mfunc Aggregation - Agg Rowset -> Row -> GetSourceRowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_17() { TBEGIN HROW hRow = NULL; CAggregate Aggregate(pIRowset()); IRow* pIRow = NULL; IGetRow* pIGetRow = NULL; IUnknown* pIAggregate = NULL; COpenRowset OpenRowsetA; CRowset RowsetA; IUnknown* pIUnkInner = NULL; ULONG ulRefCountBefore, ulRefCountAfter; // Verify that the provider supports IGetRow interface TEST_PROVIDER(SupportedInterface(IID_IGetRow,ROWSET_INTERFACE)); //Create a rowset that is Aggregated... HRESULT hr = OpenRowsetA.CreateOpenRowset(IID_IUnknown, (IUnknown**)&pIUnkInner, &Aggregate); Aggregate.SetUnkInner(pIUnkInner); //Verify Aggregation for this rowset... TESTC_PROVIDER(Aggregate.VerifyAggregationQI(hr, IID_IGetRow, (IUnknown**)&pIGetRow)); //Obtain the second row TESTC_(RowsetA.CreateRowset(pIGetRow),S_OK); TESTC_(RowsetA.GetRow(SECOND_ROW, &hRow),S_OK); //Now Create the Row (non-aggregated) //NOTE: The Aggregated row senario (GetRowFromHROW) is done in the IGetRow test since //its explicitly interested in that method. In IRow were maininly interested in testing //GetSourceRowset so we need to do the Aggregated Rowset -> Row senario... ulRefCountBefore = Aggregate.GetRefCount(); TEST2C_(hr = pIGetRow->GetRowFromHROW(NULL, hRow, IID_IRow, (IUnknown**)&pIRow),S_OK,DB_S_NOROWSPECIFICCOLUMNS); ulRefCountAfter = Aggregate.GetRefCount(); //IRow::GetSourceRowset TEST2C_(hr = pIRow->GetSourceRowset(IID_IAggregate, (IUnknown**)&pIAggregate, NULL),S_OK,DB_E_NOSOURCEOBJECT); if(hr==S_OK) { TESTC(VerifyEqualInterface(pIAggregate, pIGetRow)); //Verify the child correctly addref'd the parent outer. //The is an absolute requirement that the child keep the parent outer alive. //If it doesn't addref the outer, the outer can be released externally since //its not being used anymore due to the fact the outer controls the refcount //of the inner. Many providers incorrectly addref the inner, which does nothing //but guareentee the inner survives, but the inner will delegate to the outer //and crash since it no longer exists... TCOMPARE_(ulRefCountAfter > ulRefCountBefore); } else { TWARNING(L"IRow::GetSourceRowset unable to retrieve Parent object!"); } CLEANUP: SAFE_RELEASE(pIAggregate); SAFE_RELEASE(pIRow); SAFE_RELEASE(pIGetRow); RowsetA.ReleaseRows(hRow); SAFE_RELEASE(pIUnkInner); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(18) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_18() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(19) //*----------------------------------------------------------------------- // @mfunc Threads - GetSourceRowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_GetSourceRowset::Variation_19() { TBEGIN INIT_THREADS(MAX_THREADS); //Setup Thread Arguments THREADARG T1Arg = { this }; //Create Threads CREATE_THREADS(Thread_VerifyGetSourceRowset, &T1Arg); START_THREADS(); END_THREADS(); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_TERMINATE_METHOD //*----------------------------------------------------------------------- // @mfunc TestCase Termination Routine // // @rdesc TEST_PASS or TEST_FAIL // BOOL TCIRow_GetSourceRowset::Terminate() { // {{ TCW_TERM_BASECLASS_CHECK2 return(TCIRow::Terminate()); } // }} // }} TCW_TERMINATE_METHOD_END // }} TCW_TC_PROTOTYPE_END // {{ TCW_TC_PROTOTYPE(TCIRow_Open) //*----------------------------------------------------------------------- //| Test Case: TCIRow_Open - IRow::Open //| Created: 8/5/98 //*----------------------------------------------------------------------- //*----------------------------------------------------------------------- // @mfunc TestCase Initialization Routine // // @rdesc TRUE or FALSE // BOOL TCIRow_Open::Init() { // {{ TCW_INIT_BASECLASS_CHECK if(TCIRow::Init()) // }} { return TRUE; } return FALSE; } // {{ TCW_VAR_PROTOTYPE(1) //*----------------------------------------------------------------------- // @mfunc GUID_NULL - All columns as Default Object // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_1() { TBEGIN //IRow::Open TESTC(VerifyOpenAllRows(NULL, GUID_NULL, IID_IUnknown, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(2) //*----------------------------------------------------------------------- // @mfunc DBGUID_STREAM - All Mandatory and Optional TStream interfaces // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_2() { TBEGIN //Open all columns as Mandatory and Optional stream interfaces TESTC(VerifyOpenAllInterfaces(STREAM_INTERFACE, DBGUID_STREAM)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(3) //*----------------------------------------------------------------------- // @mfunc DBGUID_STREAM - Compare data with expected // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_3() { TBEGIN //IRow::Open TESTC(VerifyOpenAllRows(NULL, DBGUID_STREAM, IID_ISequentialStream, ALL_COLS_BOUND)); TESTC(VerifyOpenAllRows(NULL, DBGUID_STREAM, IID_IStream, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(4) //*----------------------------------------------------------------------- // @mfunc DBGUID_STREAM - Twice on the same column // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_4() { TBEGIN //Multiple Objects open TESTC(VerifyOpenWithOpenObjects(DBGUID_STREAM, IID_ISequentialStream)) TESTC(VerifyOpenWithOpenObjects(DBGUID_STREAM, IID_IStream)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(5) //*----------------------------------------------------------------------- // @mfunc DBGUID_STREAM - Multiple Objects open on different columns // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_5() { TBEGIN //Multiple Objects open TESTC(VerifyOpenWithOpenObjects(DBGUID_STREAM, IID_ISequentialStream)) TESTC(VerifyOpenWithOpenObjects(DBGUID_STREAM, IID_IStream)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(6) //*----------------------------------------------------------------------- // @mfunc DBGUID_STREAM - Bufferred Mode // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_6() { TBEGIN //Create a buffered mode rowset CRowsetUpdate RowsetA; //Not all providers will support IRowsetUpdate TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK); //IRow::Open TESTC(VerifyOpenAllRows(&RowsetA, DBGUID_STREAM, IID_IStream, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(7) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_7() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(8) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROW - All Mandatory and Optional TRow interfaces // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_8() { TBEGIN //Open all columns as Mandatory and Optional interfaces TESTC(VerifyOpenAllInterfaces(ROW_INTERFACE, DBGUID_ROW)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(9) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROW - Get all row columns and verify // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_9() { TBEGIN //IRow::Open TESTC(VerifyOpenAllRows(NULL, DBGUID_ROW, IID_IRow, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(10) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROW - GetSourceRowset // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_10() { TBEGIN //IRow::Open //This helper will call GetSourceRowset from the returned row object... TESTC(VerifyOpenWithOpenObjects(DBGUID_ROW, IID_IRow)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(11) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROW - Twice on the same column // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_11() { TBEGIN //Multiple Objects open TESTC(VerifyOpenWithOpenObjects(DBGUID_ROW, IID_IRow)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(12) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROW - Multiple Objects open on different columns // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_12() { TBEGIN //Multiple Objects open TESTC(VerifyOpenWithOpenObjects(DBGUID_ROW, IID_IRow)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(13) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROW - Bufferred Mode // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_13() { TBEGIN //Create a buffered mode rowset CRowsetUpdate RowsetA; //Not all providers will support IRowsetUpdate TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK); //IRow::Open TESTC(VerifyOpenAllRows(&RowsetA, DBGUID_ROW, IID_IRow, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(14) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_14() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(15) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROWSET - All Mandatory and Optional TRowset interfaces // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_15() { TBEGIN //Open all columns as Mandatory and Optional interfaces TESTC(VerifyOpenAllInterfaces(ROWSET_INTERFACE, DBGUID_ROWSET)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(16) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROWSET - Twice on the same column // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_16() { TBEGIN //Multiple Objects open TESTC(VerifyOpenWithOpenObjects(DBGUID_ROWSET, IID_IRowset)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(17) //*----------------------------------------------------------------------- // @mfunc DBGUID_ROWSET - Buffered mode // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_17() { TBEGIN //Create a buffered mode rowset CRowsetUpdate RowsetA; //Not all providers will support IRowsetUpdate TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK); //Multiple Objects open TESTC(VerifyOpenAllRows(&RowsetA, DBGUID_ROWSET, IID_IRowset, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(18) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_18() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(19) //*----------------------------------------------------------------------- // @mfunc DEFAULTSTREAM // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_19() { TBEGIN //VerifyOpenWithOpenObjects also takes case of the DefaultStream object... //TODO: Currently this function doesn't take care of the default stream... TESTC(VerifyOpenWithOpenObjects(DBGUID_STREAM, IID_IStream)) CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(20) //*----------------------------------------------------------------------- // @mfunc DEFAULTSTREAM - Buffered mode // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_20() { TBEGIN //Create a buffered mode rowset CRowsetUpdate RowsetA; //Not all providers will support IRowsetUpdate TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK); //Multiple Objects open TESTC(VerifyOpenAllRows(&RowsetA, DBGUID_STREAM, IID_IStream, ALL_COLS_BOUND)); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(21) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_21() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(22) //*----------------------------------------------------------------------- // @mfunc Boundary - E_INVALIDARG // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_22() { TBEGIN //We want the columnID to be correct, incase the provider validates it before the object type const DBID* pColumnID = m_pCRowObject->m_cColAccess ? &m_pCRowObject->m_rgColAccess[0].columnid : &DBROWCOL_DEFAULTSTREAM; //NOTE: We have to call directly since our helper handles this... TESTC_(m_pCRowObject->pIRow()->Open(NULL, (DBID*)pColumnID, GUID_NULL, 0, IID_IUnknown, NULL), E_INVALIDARG); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(23) //*----------------------------------------------------------------------- // @mfunc Boundary - DB_E_BADCOLUMNID - invalid DBID // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_23() { TBEGIN DBID* pColumnID = NULL; DBKIND iKind = 0; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); SAFE_ALLOC(pColumnID, DBID, 1); //Loop through all possible DBKINDs for(iKind=0; iKindeKind = iKind % (DBKIND_GUID+1); TESTC_(CreateUniqueDBID(pColumnID, TRUE/*fInitialize*/),S_OK); //DB_E_BADCOLUMNID - invalid DBID TESTC_(RowObjectA.Open(NULL, pColumnID, GUID_NULL, IID_IUnknown), DB_E_BADCOLUMNID); //Error depends upon order of validation in the provider TEST2C_(RowObjectA.Open(NULL, pColumnID, DBGUID_ROWSET, IID_IRowset), DB_E_BADCOLUMNID, DB_E_OBJECTMISMATCH); TEST2C_(RowObjectA.Open(NULL, pColumnID, DBGUID_ROW, IID_IRow), DB_E_BADCOLUMNID, DB_E_OBJECTMISMATCH); TEST2C_(RowObjectA.Open(NULL, pColumnID, DBGUID_STREAM, IID_ISequentialStream), DB_E_BADCOLUMNID, DB_E_OBJECTMISMATCH); ReleaseDBID(pColumnID, FALSE/*fDrop*/); } CLEANUP: ReleaseDBID(pColumnID, TRUE/*fDrop*/); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(24) //*----------------------------------------------------------------------- // @mfunc Boundary - DB_E_BADCOLUMNID - invalid [but close to original] DBID // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_24() { TBEGIN DBORDINAL iCol = 0; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Loop through all current columns for(iCol=0; iColeKind) { case DBKIND_GUID_NAME: case DBKIND_PGUID_NAME: { GUID guid; //Create a "unique" string SAFE_FREE(pColumnID->uName.pwszName); //For every other "name" column - well use NULL if(iCol%2) { TESTC_(CoCreateGuid(&guid),S_OK); TESTC_(StringFromCLSID(guid, &pColumnID->uName.pwszName),S_OK); } break; } default: { //Otherwise just create a completely unique name... //For two-part it changes the GUID, so all we really have left is to verify //that only changing the name is caught... TESTC_(CreateUniqueDBID(pColumnID, TRUE/*fInitialize*/),S_OK); break; } }; //DB_E_BADCOLUMNID - invalid DBID TESTC_(RowObjectA.Open(NULL, pColumnID, GUID_NULL, IID_IUnknown), DB_E_BADCOLUMNID); //Error depends upon order of validation in the provider TEST2C_(RowObjectA.Open(NULL, pColumnID, DBGUID_ROWSET, IID_IRowset), DB_E_BADCOLUMNID, DB_E_OBJECTMISMATCH); TEST2C_(RowObjectA.Open(NULL, pColumnID, DBGUID_ROW, IID_IRow), DB_E_BADCOLUMNID, DB_E_OBJECTMISMATCH); TEST2C_(RowObjectA.Open(NULL, pColumnID, DBGUID_STREAM, IID_ISequentialStream), DB_E_BADCOLUMNID, DB_E_OBJECTMISMATCH); } CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(25) //*----------------------------------------------------------------------- // @mfunc Boundary - DB_E_BADCOLUMNID - shortcut DBID that doesn't exist // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_25() { TBEGIN ULONG i=0; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Loop through all possible DBROWCOLs for(i=0; im_cColAccess ? &m_pCRowObject->m_rgColAccess[0].columnid : &DBROWCOL_DEFAULTSTREAM; //DB_E_OBJECTMISMATCH - invalid Object type TESTC_(m_pCRowObject->Open(NULL, pColumnID, CLSID_MSDASQL, IID_IUnknown), DB_E_OBJECTMISMATCH); CLEANUP: TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(27) //*----------------------------------------------------------------------- // @mfunc Boundary - DB_E_OBJECTOPEN // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_27() { // TO DO: Add your own code here return TRUE; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(28) //*----------------------------------------------------------------------- // @mfunc Boundary - DB_E_NOTFOUND // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_28() { // TO DO: Add your own code here return TRUE; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(29) //*----------------------------------------------------------------------- // @mfunc Boundary - DB_E_DELETEDROW // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_29() { // TO DO: Add your own code here return TRUE; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(30) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_30() { return TEST_SKIPPED; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(31) //*----------------------------------------------------------------------- // @mfunc Stream Object - Read the data in chunks // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_31() { TBEGIN IUnknown* pIUnknown = NULL; ULONG cbRead = 0; ULONG cbTotal = 0; BYTE* rgBytes = NULL; BYTE* rgBytes2 = NULL; HRESULT hr = S_OK; DBID* pColumnID = NULL; //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Obtain a stream object if(SUCCEEDED(FindObject(&RowObjectA, NULL, DBGUID_STREAM, IID_IUnknown, &pIUnknown, &pColumnID))) { //First read the stream (in chunks)... while(SUCCEEDED(hr)) { SAFE_REALLOC(rgBytes, BYTE, cbTotal + 10); TEST2C_(hr = StorageRead(IID_IUnknown, pIUnknown, rgBytes + cbTotal, 10, &cbRead),S_OK,S_FALSE); cbTotal += cbRead; if(cbRead == 0) break; } //Now close the stream and open it again //NOTE: We have to completely recreate the row object, since the Data could be Forward-Only... SAFE_RELEASE(pIUnknown); TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Obtain the stream again TESTC_(RowObjectA.Open(NULL, pColumnID, DBGUID_STREAM, IID_IUnknown, &pIUnknown),S_OK); //Now a third of the bytes (should succeed, not at the end) SAFE_REALLOC(rgBytes2, BYTE, cbTotal/3); TESTC_(hr = StorageRead(IID_IUnknown, pIUnknown, rgBytes2, cbTotal/3, &cbRead), S_OK); TESTC(cbTotal/3 == cbRead); //Make sure these are are the same as the first read TESTC(memcmp(rgBytes, rgBytes2, cbRead)==0); //Now close the stream before all the data is read, and reopen it... SAFE_RELEASE(pIUnknown); TEST2C_(hr = RowObjectA.Open(NULL, pColumnID, DBGUID_STREAM, IID_IUnknown, &pIUnknown),S_OK, DB_E_COLUMNUNAVAILABLE); if(SUCCEEDED(hr)) { //Read again - this should return the data starting at the begining, not where the //previous stream left off (common mistake). This should be idential to GetData/GetColumns //when called again returns the data again. SAFE_REALLOC(rgBytes2, BYTE, cbTotal+1); TEST2C_(hr = StorageRead(IID_IUnknown, pIUnknown, rgBytes2, cbTotal+1, &cbRead), S_OK, S_FALSE); TESTC(cbTotal == cbRead); //Compare the data to the original returned. TESTC(memcmp(rgBytes, rgBytes2, cbRead)==0); } else { TWARNING("Provider doesn't support reading the data twice..."); } } else { TWARNING("Unable to open any stream object on the row?"); } CLEANUP: ReleaseDBID(pColumnID); SAFE_RELEASE(pIUnknown); SAFE_FREE(rgBytes); TRETURN } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(32) //*----------------------------------------------------------------------- // @mfunc Empty // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_32() { // TO DO: Add your own code here return TRUE; } // }} TCW_VAR_PROTOTYPE_END // {{ TCW_VAR_PROTOTYPE(33) //*----------------------------------------------------------------------- // @mfunc Aggregation - Row -> Open -> GetSourceRow // // @rdesc TEST_PASS or TEST_FAIL // int TCIRow_Open::Variation_33() { TBEGIN HRESULT hr = S_OK; DBORDINAL i,cColAccess = 0; DBCOLUMNACCESS* rgColAccess = NULL; void* pData = NULL; IUnknown* pUnkInner = NULL; CAggregate Aggregate; //NOTE: The Aggregated Row object senario (Agg Row -> Open -> GetSourceRow) is handled //in the GetSourceRow test. In this senario we are mainly interested in have the object //opened aggregated, hence the reason for testing IRow::Open... //Obtain a row object CRowObject RowObjectA; TESTC_(GetRowObject(FIRST_ROW, &RowObjectA), S_OK); //Create the ColAccess Structures... TESTC_(hr = RowObjectA.CreateColAccess(&cColAccess, &rgColAccess, &pData),S_OK); //IRow::Open (for all bound columns) for(i=0; i