11329 lines
326 KiB
C++
11329 lines
326 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright (C) 1995-2000 Microsoft Corporation
|
|
//
|
|
// @doc
|
|
//
|
|
// @module IRUpdate.cpp | This module tests the OLEDB IRowsetUpdate interface
|
|
//
|
|
|
|
#include "MODStandard.hpp" // Standard headers
|
|
#include "IRUpdate.h" // IRowsetUpdate header
|
|
#include "msdasql.h" // KAGPROP_QUERYBASEDUPDATES
|
|
#include "ExtraLib.h"
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Module Values
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// {{ TCW_MODULE_GLOBALS
|
|
DECLARE_MODULE_CLSID = { 0x0bb5a150, 0x8cce, 0x11cf, { 0xaa, 0x41, 0x00, 0xaa, 0x00, 0x3e, 0x77, 0x8a }};
|
|
DECLARE_MODULE_NAME("IRowsetUpdate");
|
|
DECLARE_MODULE_OWNER("Microsoft");
|
|
DECLARE_MODULE_DESCRIP("IRowsetUpdate interface test");
|
|
DECLARE_MODULE_VERSION(838070366);
|
|
// }}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level initialization routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleInit(CThisTestModule * pThisTestModule)
|
|
{
|
|
return CommonModuleInit(pThisTestModule, IID_IRowsetUpdate, FOURTEEN_ROWS);
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level termination routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleTerminate(CThisTestModule * pThisTestModule)
|
|
{
|
|
return CommonModuleTerminate(pThisTestModule);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowsetUpdate
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
class TCIRowsetUpdate : public CRowsetUpdate
|
|
{
|
|
public:
|
|
//constructors
|
|
TCIRowsetUpdate(WCHAR* pwszTestCaseName = INVALID(WCHAR*));
|
|
virtual ~TCIRowsetUpdate();
|
|
|
|
//methods
|
|
virtual BOOL Init();
|
|
virtual BOOL Terminate();
|
|
|
|
virtual BOOL VerifyAddRefRows
|
|
(
|
|
ULONG cRows,
|
|
HROW* rghRows,
|
|
ULONG ulRefCount = 0,
|
|
DBROWSTATUS dwRowStatus = DBROWSTATUS_S_OK
|
|
);
|
|
|
|
virtual BOOL VerifyReleaseRows
|
|
(
|
|
ULONG cRows,
|
|
HROW* rghRows,
|
|
ULONG ulRefCount = 0,
|
|
DBROWSTATUS dwRowStatus = DBROWSTATUS_S_OK
|
|
);
|
|
|
|
//@mfunc: verify the reference counts for an array of RefCounts
|
|
virtual BOOL VerifyRowStatus
|
|
(
|
|
ULONG cRows, //[in] cRows
|
|
DBROWSTATUS* rgRowStatus, //[in] rgRowStatus
|
|
DBROWSTATUS dwRowStatus = DBROWSTATUS_S_OK //[in] Expected RowStatus
|
|
);
|
|
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowsetUpdate::TCIRowsetUpdate
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
TCIRowsetUpdate::TCIRowsetUpdate(WCHAR * wstrTestCaseName) : CRowsetUpdate(wstrTestCaseName)
|
|
{
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowsetUpdate::~TCIRowsetUpdate
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
TCIRowsetUpdate::~TCIRowsetUpdate()
|
|
{
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowsetUpdate::Init
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowsetUpdate::Init()
|
|
{
|
|
return CRowsetUpdate::Init();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowsetUpdate::Terminate
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowsetUpdate::Terminate()
|
|
{
|
|
return CRowsetUpdate::Terminate();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowsetUpdate::VerifyReleaseRows
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowsetUpdate::VerifyReleaseRows
|
|
(
|
|
ULONG cRows,
|
|
HROW* rghRows,
|
|
ULONG ulRefCount,
|
|
DBROWSTATUS dwRowStatus
|
|
)
|
|
{
|
|
TBEGIN
|
|
ULONG* rgRefCounts = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
if(cRows && rghRows)
|
|
{
|
|
//Release the rows
|
|
TESTC_(ReleaseRows(cRows, rghRows, &rgRefCounts, &rgRowStatus),S_OK);
|
|
TESTC(rgRefCounts != NULL && rgRowStatus != NULL);
|
|
|
|
//Verify the ref counts and status
|
|
QTESTC(VerifyRefCounts(cRows, rgRefCounts, ulRefCount));
|
|
QTESTC(VerifyRowStatus(cRows, rgRowStatus, dwRowStatus));
|
|
}
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgRefCounts);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowsetUpdate::VerifyAddRefRows
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowsetUpdate::VerifyAddRefRows
|
|
(
|
|
ULONG cRows,
|
|
HROW* rghRows,
|
|
ULONG ulRefCount,
|
|
DBROWSTATUS dwRowStatus
|
|
)
|
|
{
|
|
TBEGIN
|
|
ULONG* rgRefCounts = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
if(cRows && rghRows)
|
|
{
|
|
rgRefCounts = PROVIDER_ALLOC_(cRows, ULONG);
|
|
rgRowStatus = PROVIDER_ALLOC_(cRows, DBROWSTATUS);
|
|
TESTC(rgRefCounts != NULL);
|
|
TESTC(rgRowStatus != NULL);
|
|
|
|
//AddRef the rows
|
|
TESTC_(pIRowset()->AddRefRows(cRows, rghRows, rgRefCounts, rgRowStatus),S_OK);
|
|
|
|
//Verify the ref count / row status
|
|
TESTC(VerifyRefCounts(cRows, rgRefCounts, ulRefCount));
|
|
TESTC(VerifyRowStatus(cRows, rgRowStatus, dwRowStatus));
|
|
}
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgRefCounts);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCIRowsetUpdate::VerifyRowStatus
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
BOOL TCIRowsetUpdate::VerifyRowStatus
|
|
(
|
|
ULONG cRows, //[in] cRows
|
|
DBROWSTATUS* rgRowStatus, //[in] rgRowStatus
|
|
DBROWSTATUS dwRowStatus //[in] Expected RowStatus
|
|
)
|
|
{
|
|
//every element in the ref count array should be the same as cExpected
|
|
for(ULONG i=0; i<cRows; i++)
|
|
{
|
|
if(rgRowStatus[i] != dwRowStatus)
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCGetOriginalRows)
|
|
//--------------------------------------------------------------------
|
|
// @class IRowsetUpdate::GetOriginalRows test case
|
|
//
|
|
class TCGetOriginalRows : public CRowsetUpdate {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCGetOriginalRows,CRowsetUpdate);
|
|
// }}
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - IID_IRowsetUpdate on a read-only rowset
|
|
int Variation_1();
|
|
// @cmember General - IID_IRowsetUpdate on a read-only rowset, created with OuterJoin
|
|
int Variation_2();
|
|
// @cmember General - IID_IRowsetChange implicitly set on IID_IRowsetUpdate
|
|
int Variation_3();
|
|
// @cmember General - IID_IRowsetUpdate is not exposed on IRowsetChange
|
|
int Variation_4();
|
|
// @cmember General - IID_IRowsetLocate exposed on IRowsetUpdate
|
|
int Variation_5();
|
|
// @cmember General - QueryI(invalid, valid
|
|
int Variation_6();
|
|
// @cmember General - QueryI(valid, NULL
|
|
int Variation_7();
|
|
// @cmember General - QueryI(IID_IRowsetUpdate, valid
|
|
int Variation_8();
|
|
// @cmember General - QueryI(IID_IRowsetChange, valid
|
|
int Variation_9();
|
|
// @cmember General - IRowsetChange->QueryI(IID_IRowsetUpdate, valid
|
|
int Variation_10();
|
|
// @cmember General - Verify AddRef / Release
|
|
int Variation_11();
|
|
// @cmember General - Verify RefCount or row handles
|
|
int Variation_12();
|
|
// @cmember Boundary - [NULL Accessor]
|
|
int Variation_13();
|
|
// @cmember Boundary - [PASSBYREF NULL Accessor]
|
|
int Variation_14();
|
|
// @cmember Boundary - [valid, valid, NULL]
|
|
int Variation_15();
|
|
// @cmember Boundary - [DB_INVALID_ROW, valid, valid]
|
|
int Variation_16();
|
|
// @cmember Boundary - [valid, DB_NULL_HACCESSOR, valid]
|
|
int Variation_17();
|
|
// @cmember Boundary - Call GetOriginalData before any other method
|
|
int Variation_18();
|
|
// @cmember Empty
|
|
int Variation_19();
|
|
// @cmember Parameters - Hard deleted row
|
|
int Variation_20();
|
|
// @cmember Parameters - Soft Deleted row, No update
|
|
int Variation_21();
|
|
// @cmember Parameters - Newly inserted row, No update
|
|
int Variation_22();
|
|
// @cmember Parameters - Newly inserted row - NULL Accessor, No update
|
|
int Variation_23();
|
|
// @cmember Parameters - A modified row, No update
|
|
int Variation_24();
|
|
// @cmember Parameters - An inserted, modified row
|
|
int Variation_25();
|
|
// @cmember Parameters - A newly inserted row, update
|
|
int Variation_26();
|
|
// @cmember Parameters - A newly inserted row - NULL Accessor, update
|
|
int Variation_27();
|
|
// @cmember Parameters - A modified row, update
|
|
int Variation_28();
|
|
// @cmember Parameters - An inserted/modified row, update
|
|
int Variation_29();
|
|
// @cmember Parameters - Insert/Modify/Delete all rows
|
|
int Variation_30();
|
|
// @cmember Empty
|
|
int Variation_31();
|
|
// @cmember Empty
|
|
int Variation_32();
|
|
// @cmember Empty
|
|
int Variation_33();
|
|
// @cmember Empty
|
|
int Variation_34();
|
|
// @cmember Empty
|
|
int Variation_35();
|
|
// @cmember Empty
|
|
int Variation_36();
|
|
// @cmember Empty
|
|
int Variation_37();
|
|
// @cmember Accessor - BLOB / Long columns - SetPos
|
|
int Variation_38();
|
|
// @cmember Accessor - BLOB / Long columns - QBU
|
|
int Variation_39();
|
|
// @cmember Empty
|
|
int Variation_40();
|
|
// @cmember Parameters - DB_E_BADACCESSORTYPE
|
|
int Variation_41();
|
|
// @cmember Parameters - DB_E_SEC_E_PERMISSIONDENIED
|
|
int Variation_42();
|
|
// @cmember Parameters - DB_E_BADBINDINFO
|
|
int Variation_43();
|
|
// @cmember Parameters - DB_E_COLUMNUNAVAILABLE
|
|
int Variation_44();
|
|
// @cmember Empty
|
|
int Variation_45();
|
|
// @cmember Sequence - Call GetOriginalData 3 times
|
|
int Variation_46();
|
|
// }}
|
|
};
|
|
// {{ TCW_TESTCASE(TCGetOriginalRows)
|
|
#define THE_CLASS TCGetOriginalRows
|
|
BEG_TEST_CASE(TCGetOriginalRows, CRowsetUpdate, L"IRowsetUpdate::GetOriginalRows test case")
|
|
TEST_VARIATION(1, L"General - IID_IRowsetUpdate on a read-only rowset")
|
|
TEST_VARIATION(2, L"General - IID_IRowsetUpdate on a read-only rowset, created with OuterJoin")
|
|
TEST_VARIATION(3, L"General - IID_IRowsetChange implicitly set on IID_IRowsetUpdate")
|
|
TEST_VARIATION(4, L"General - IID_IRowsetUpdate is not exposed on IRowsetChange")
|
|
TEST_VARIATION(5, L"General - IID_IRowsetLocate exposed on IRowsetUpdate")
|
|
TEST_VARIATION(6, L"General - QueryI(invalid, valid")
|
|
TEST_VARIATION(7, L"General - QueryI(valid, NULL")
|
|
TEST_VARIATION(8, L"General - QueryI(IID_IRowsetUpdate, valid")
|
|
TEST_VARIATION(9, L"General - QueryI(IID_IRowsetChange, valid")
|
|
TEST_VARIATION(10, L"General - IRowsetChange->QueryI(IID_IRowsetUpdate, valid")
|
|
TEST_VARIATION(11, L"General - Verify AddRef / Release")
|
|
TEST_VARIATION(12, L"General - Verify RefCount or row handles")
|
|
TEST_VARIATION(13, L"Boundary - [NULL Accessor]")
|
|
TEST_VARIATION(14, L"Boundary - [PASSBYREF NULL Accessor]")
|
|
TEST_VARIATION(15, L"Boundary - [valid, valid, NULL]")
|
|
TEST_VARIATION(16, L"Boundary - [DB_INVALID_ROW, valid, valid]")
|
|
TEST_VARIATION(17, L"Boundary - [valid, DB_NULL_HACCESSOR, valid]")
|
|
TEST_VARIATION(18, L"Boundary - Call GetOriginalData before any other method")
|
|
TEST_VARIATION(19, L"Empty")
|
|
TEST_VARIATION(20, L"Parameters - Hard deleted row")
|
|
TEST_VARIATION(21, L"Parameters - Soft Deleted row, No update")
|
|
TEST_VARIATION(22, L"Parameters - Newly inserted row, No update")
|
|
TEST_VARIATION(23, L"Parameters - Newly inserted row - NULL Accessor, No update")
|
|
TEST_VARIATION(24, L"Parameters - A modified row, No update")
|
|
TEST_VARIATION(25, L"Parameters - An inserted, modified row")
|
|
TEST_VARIATION(26, L"Parameters - A newly inserted row, update")
|
|
TEST_VARIATION(27, L"Parameters - A newly inserted row - NULL Accessor, update")
|
|
TEST_VARIATION(28, L"Parameters - A modified row, update")
|
|
TEST_VARIATION(29, L"Parameters - An inserted/modified row, update")
|
|
TEST_VARIATION(30, L"Parameters - Insert/Modify/Delete all rows")
|
|
TEST_VARIATION(31, L"Empty")
|
|
TEST_VARIATION(32, L"Empty")
|
|
TEST_VARIATION(33, L"Empty")
|
|
TEST_VARIATION(34, L"Empty")
|
|
TEST_VARIATION(35, L"Empty")
|
|
TEST_VARIATION(36, L"Empty")
|
|
TEST_VARIATION(37, L"Empty")
|
|
TEST_VARIATION(38, L"Accessor - BLOB / Long columns - SetPos")
|
|
TEST_VARIATION(39, L"Accessor - BLOB / Long columns - QBU")
|
|
TEST_VARIATION(40, L"Empty")
|
|
TEST_VARIATION(41, L"Parameters - DB_E_BADACCESSORTYPE")
|
|
TEST_VARIATION(42, L"Parameters - DB_E_SEC_E_PERMISSIONDENIED")
|
|
TEST_VARIATION(43, L"Parameters - DB_E_BADBINDINFO")
|
|
TEST_VARIATION(44, L"Parameters - DB_E_COLUMNUNAVAILABLE")
|
|
TEST_VARIATION(45, L"Empty")
|
|
TEST_VARIATION(46, L"Sequence - Call GetOriginalData 3 times")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCGetPendingRows)
|
|
//--------------------------------------------------------------------
|
|
// @class IRowsetUpdate::GetPendingRows test case
|
|
//
|
|
class TCGetPendingRows : public CRowsetUpdate {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCGetPendingRows,CRowsetUpdate);
|
|
// }}
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - Verify GetPendingRows alters row handles correctly
|
|
int Variation_1();
|
|
// @cmember Boundary - N Changes [NULL, _ALL, NULL, NULL]
|
|
int Variation_2();
|
|
// @cmember Boundary - N Changes [invalid, _ALL, NULL, invalid, invalid]
|
|
int Variation_3();
|
|
// @cmember Boundary - N Changes [NULL, _ALL, valid, NULL, NULL]
|
|
int Variation_4();
|
|
// @cmember Boundary - N Changes [NULL, _ALL, valid, NULL, valid]
|
|
int Variation_5();
|
|
// @cmember Boundary - N Changes [NULL, _ALL, valid, valid, NULL]
|
|
int Variation_6();
|
|
// @cmember Boundary - No Changes [NULL, _ALL, NULL, NULL, NULL]
|
|
int Variation_7();
|
|
// @cmember Boundary - No Changes [NULL, _ALL, valid, NULL, NULL]
|
|
int Variation_8();
|
|
// @cmember Boundary - No Changes [NULL, _ALL, valid, valid, NULL]
|
|
int Variation_9();
|
|
// @cmember Boundary - No Changes [NULL, _ALL, valid, valid, valid]
|
|
int Variation_10();
|
|
// @cmember Boundary - No Changes (NULL, _ALL, valid, NULL, valid
|
|
int Variation_11();
|
|
// @cmember Boundary - Empty Rowset [NULL, _ALL, valid, valid, valid]
|
|
int Variation_12();
|
|
// @cmember Empty
|
|
int Variation_13();
|
|
// @cmember Parameters - DBROWSTATUS seperately, before any changes
|
|
int Variation_14();
|
|
// @cmember Parameters - DBPENDINGSTATUS_INVALIDROW
|
|
int Variation_15();
|
|
// @cmember Parameters - DBROWSTATUS _NEW | _CHANGED | _SOFTDELETED
|
|
int Variation_16();
|
|
// @cmember Parameters - DBPENDINGSTATUS_NEW, w/ no new rows
|
|
int Variation_17();
|
|
// @cmember Parameters - DBPENDINGSTATUS_CHANGED, w/ no changed rows
|
|
int Variation_18();
|
|
// @cmember Parameters - DBPENDINGSTATUS_UNCHANGED, w/ all changed rows
|
|
int Variation_19();
|
|
// @cmember Parameters - DBPENDINGSTATUS_DELETED, w/ no soft-deleted rows
|
|
int Variation_20();
|
|
// @cmember Empty
|
|
int Variation_21();
|
|
// @cmember Parameters - _NEW | _UNCHANGED
|
|
int Variation_22();
|
|
// @cmember Parameters - _NEW | _SOFTDELETED
|
|
int Variation_23();
|
|
// @cmember Empty
|
|
int Variation_24();
|
|
// @cmember Parameters - Insert/Modify/Delete a single row
|
|
int Variation_25();
|
|
// @cmember Empty
|
|
int Variation_26();
|
|
// @cmember Sequence - Call GetPendingRows 3 times
|
|
int Variation_27();
|
|
// @cmember Sequence - Modify the same row twice
|
|
int Variation_28();
|
|
// @cmember Sequence - Modify the same row twice, undo, GetPendingRows
|
|
int Variation_29();
|
|
// }}
|
|
};
|
|
// {{ TCW_TESTCASE(TCGetPendingRows)
|
|
#define THE_CLASS TCGetPendingRows
|
|
BEG_TEST_CASE(TCGetPendingRows, CRowsetUpdate, L"IRowsetUpdate::GetPendingRows test case")
|
|
TEST_VARIATION(1, L"General - Verify GetPendingRows alters row handles correctly")
|
|
TEST_VARIATION(2, L"Boundary - N Changes [NULL, _ALL, NULL, NULL]")
|
|
TEST_VARIATION(3, L"Boundary - N Changes [invalid, _ALL, NULL, invalid, invalid]")
|
|
TEST_VARIATION(4, L"Boundary - N Changes [NULL, _ALL, valid, NULL, NULL]")
|
|
TEST_VARIATION(5, L"Boundary - N Changes [NULL, _ALL, valid, NULL, valid]")
|
|
TEST_VARIATION(6, L"Boundary - N Changes [NULL, _ALL, valid, valid, NULL]")
|
|
TEST_VARIATION(7, L"Boundary - No Changes [NULL, _ALL, NULL, NULL, NULL]")
|
|
TEST_VARIATION(8, L"Boundary - No Changes [NULL, _ALL, valid, NULL, NULL]")
|
|
TEST_VARIATION(9, L"Boundary - No Changes [NULL, _ALL, valid, valid, NULL]")
|
|
TEST_VARIATION(10, L"Boundary - No Changes [NULL, _ALL, valid, valid, valid]")
|
|
TEST_VARIATION(11, L"Boundary - No Changes (NULL, _ALL, valid, NULL, valid")
|
|
TEST_VARIATION(12, L"Boundary - Empty Rowset [NULL, _ALL, valid, valid, valid]")
|
|
TEST_VARIATION(13, L"Empty")
|
|
TEST_VARIATION(14, L"Parameters - DBROWSTATUS seperately, before any changes")
|
|
TEST_VARIATION(15, L"Parameters - DBPENDINGSTATUS_INVALIDROW")
|
|
TEST_VARIATION(16, L"Parameters - DBROWSTATUS _NEW | _CHANGED | _SOFTDELETED")
|
|
TEST_VARIATION(17, L"Parameters - DBPENDINGSTATUS_NEW, w/ no new rows")
|
|
TEST_VARIATION(18, L"Parameters - DBPENDINGSTATUS_CHANGED, w/ no changed rows")
|
|
TEST_VARIATION(19, L"Parameters - DBPENDINGSTATUS_UNCHANGED, w/ all changed rows")
|
|
TEST_VARIATION(20, L"Parameters - DBPENDINGSTATUS_DELETED, w/ no soft-deleted rows")
|
|
TEST_VARIATION(21, L"Empty")
|
|
TEST_VARIATION(22, L"Parameters - _NEW | _UNCHANGED")
|
|
TEST_VARIATION(23, L"Parameters - _NEW | _SOFTDELETED")
|
|
TEST_VARIATION(24, L"Empty")
|
|
TEST_VARIATION(25, L"Parameters - Insert/Modify/Delete a single row")
|
|
TEST_VARIATION(26, L"Empty")
|
|
TEST_VARIATION(27, L"Sequence - Call GetPendingRows 3 times")
|
|
TEST_VARIATION(28, L"Sequence - Modify the same row twice")
|
|
TEST_VARIATION(29, L"Sequence - Modify the same row twice, undo, GetPendingRows")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCUndo)
|
|
//--------------------------------------------------------------------
|
|
// @class IRowsetUpdate::Undo test case
|
|
//
|
|
class TCUndo : public CRowsetUpdate {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCUndo,CRowsetUpdate);
|
|
// }}
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Boundary - No Changes [NULL, 0, NULL, NULL, NULL]
|
|
int Variation_1();
|
|
// @cmember Boundary - No Changes [NULL, N, valid, NULL, NULL]
|
|
int Variation_2();
|
|
// @cmember Boundary - No Changes [NULL,0,NULL, valid, valid]
|
|
int Variation_3();
|
|
// @cmember Boundary - No Changes [invalid, 1, NULL, valid, valid]
|
|
int Variation_4();
|
|
// @cmember Boundary - N Changes [NULL, 0, NULL, NULL, valid]
|
|
int Variation_5();
|
|
// @cmember Boundary - N Changes [NULL, 0, valid, valid, valid]
|
|
int Variation_6();
|
|
// @cmember Boundary - N Changes [NULL, N, valid, NULL, NULL]
|
|
int Variation_7();
|
|
// @cmember Boundary - N Changes [NULL, N, valid, valid, valid]
|
|
int Variation_8();
|
|
// @cmember Boundary - N Changes [invalid, N, NULL, valid, valid]
|
|
int Variation_9();
|
|
// @cmember Boundary - N Changes [invalid, N, valid, valid, NULL]
|
|
int Variation_10();
|
|
// @cmember Empty
|
|
int Variation_11();
|
|
// @cmember Parameters - 3 invalid / 2 modified
|
|
int Variation_12();
|
|
// @cmember Parameters - 1 hard del / 1 invalid / 1 modified
|
|
int Variation_13();
|
|
// @cmember Parameters - 1 hard del / 1 invalid
|
|
int Variation_14();
|
|
// @cmember Parameters - 3 soft del / 2 orginal
|
|
int Variation_15();
|
|
// @cmember Parameters - 3 new rows / 1 orginal
|
|
int Variation_16();
|
|
// @cmember Parameters - 4 modified / 3 orginal
|
|
int Variation_17();
|
|
// @cmember Parameters - 3 soft del / 2 orginal, update
|
|
int Variation_18();
|
|
// @cmember Parameters - 3 new rows / 1 orginal, update
|
|
int Variation_19();
|
|
// @cmember Parameters - 4 modified / 3 orginal, update
|
|
int Variation_20();
|
|
// @cmember Parameters - 3 hard del / 2 modified
|
|
int Variation_21();
|
|
// @cmember Parameters - Insert/Modify/Delete a single row
|
|
int Variation_22();
|
|
// @cmember Parameters - Insert/Modify/Delete a single row, Update
|
|
int Variation_23();
|
|
// @cmember Parameters - Duplicate entries in the array
|
|
int Variation_24();
|
|
// @cmember Empty
|
|
int Variation_25();
|
|
// @cmember Sequence - Fetch every other row, modify every even, undo all odd.
|
|
int Variation_26();
|
|
// @cmember Sequence - Call Undo 3 times
|
|
int Variation_27();
|
|
// @cmember Empty
|
|
int Variation_28();
|
|
// @cmember Boundary - Empty Rowset [NULL, 0 ,NULL, valid, valid]
|
|
int Variation_29();
|
|
// @cmember Empty
|
|
int Variation_30();
|
|
// @cmember Accessor - BLOB / Long columns - SetPos
|
|
int Variation_31();
|
|
// @cmember Accessor - BLOB / Long columns - QBU
|
|
int Variation_32();
|
|
// @cmember Empty
|
|
int Variation_33();
|
|
// @cmember General - Soft-Deleted/Undo verify valid row handle
|
|
int Variation_34();
|
|
// @cmember General - Inserted/Undo verify invalid row handle
|
|
int Variation_35();
|
|
// @cmember General - Modified/Undo verify valid row handle, and OriginalData
|
|
int Variation_36();
|
|
// @cmember General - Verify Undo alters row handle refcount correctly
|
|
int Variation_37();
|
|
// }}
|
|
};
|
|
// {{ TCW_TESTCASE(TCUndo)
|
|
#define THE_CLASS TCUndo
|
|
BEG_TEST_CASE(TCUndo, CRowsetUpdate, L"IRowsetUpdate::Undo test case")
|
|
TEST_VARIATION(1, L"Boundary - No Changes [NULL, 0, NULL, NULL, NULL]")
|
|
TEST_VARIATION(2, L"Boundary - No Changes [NULL, N, valid, NULL, NULL]")
|
|
TEST_VARIATION(3, L"Boundary - No Changes [NULL,0,NULL, valid, valid]")
|
|
TEST_VARIATION(4, L"Boundary - No Changes [invalid, 1, NULL, valid, valid]")
|
|
TEST_VARIATION(5, L"Boundary - N Changes [NULL, 0, NULL, NULL, valid]")
|
|
TEST_VARIATION(6, L"Boundary - N Changes [NULL, 0, valid, valid, valid]")
|
|
TEST_VARIATION(7, L"Boundary - N Changes [NULL, N, valid, NULL, NULL]")
|
|
TEST_VARIATION(8, L"Boundary - N Changes [NULL, N, valid, valid, valid]")
|
|
TEST_VARIATION(9, L"Boundary - N Changes [invalid, N, NULL, valid, valid]")
|
|
TEST_VARIATION(10, L"Boundary - N Changes [invalid, N, valid, valid, NULL]")
|
|
TEST_VARIATION(11, L"Empty")
|
|
TEST_VARIATION(12, L"Parameters - 3 invalid / 2 modified")
|
|
TEST_VARIATION(13, L"Parameters - 1 hard del / 1 invalid / 1 modified")
|
|
TEST_VARIATION(14, L"Parameters - 1 hard del / 1 invalid")
|
|
TEST_VARIATION(15, L"Parameters - 3 soft del / 2 orginal")
|
|
TEST_VARIATION(16, L"Parameters - 3 new rows / 1 orginal")
|
|
TEST_VARIATION(17, L"Parameters - 4 modified / 3 orginal")
|
|
TEST_VARIATION(18, L"Parameters - 3 soft del / 2 orginal, update")
|
|
TEST_VARIATION(19, L"Parameters - 3 new rows / 1 orginal, update")
|
|
TEST_VARIATION(20, L"Parameters - 4 modified / 3 orginal, update")
|
|
TEST_VARIATION(21, L"Parameters - 3 hard del / 2 modified")
|
|
TEST_VARIATION(22, L"Parameters - Insert/Modify/Delete a single row")
|
|
TEST_VARIATION(23, L"Parameters - Insert/Modify/Delete a single row, Update")
|
|
TEST_VARIATION(24, L"Parameters - Duplicate entries in the array")
|
|
TEST_VARIATION(25, L"Empty")
|
|
TEST_VARIATION(26, L"Sequence - Fetch every other row, modify every even, undo all odd.")
|
|
TEST_VARIATION(27, L"Sequence - Call Undo 3 times")
|
|
TEST_VARIATION(28, L"Empty")
|
|
TEST_VARIATION(29, L"Boundary - Empty Rowset [NULL, 0 ,NULL, valid, valid]")
|
|
TEST_VARIATION(30, L"Empty")
|
|
TEST_VARIATION(31, L"Accessor - BLOB / Long columns - SetPos")
|
|
TEST_VARIATION(32, L"Accessor - BLOB / Long columns - QBU")
|
|
TEST_VARIATION(33, L"Empty")
|
|
TEST_VARIATION(34, L"General - Soft-Deleted/Undo verify valid row handle")
|
|
TEST_VARIATION(35, L"General - Inserted/Undo verify invalid row handle")
|
|
TEST_VARIATION(36, L"General - Modified/Undo verify valid row handle, and OriginalData")
|
|
TEST_VARIATION(37, L"General - Verify Undo alters row handle refcount correctly")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCUpdate)
|
|
//--------------------------------------------------------------------
|
|
// @class IRowsetUpdate::Update test case
|
|
//
|
|
class TCUpdate : public CRowsetUpdate {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCUpdate,CRowsetUpdate);
|
|
// }}
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Boundary - No Changes [NULL, 0, NULL,NULL,NULL,NULL,NULL]
|
|
int Variation_1();
|
|
// @cmember Boundary - No Changes (NULL, 0, NULL, valid, valid, valid, valid
|
|
int Variation_2();
|
|
// @cmember Boundary - N Changes (NULL, N, valid, NULL, NULL, valid, valid
|
|
int Variation_3();
|
|
// @cmember Boundary - N Changes (invalid, N, NULL, valid, valid, valid, valid
|
|
int Variation_4();
|
|
// @cmember Boundary - N Changes (invalid, N, valid, valid, NULL, valid, valid
|
|
int Variation_5();
|
|
// @cmember Boundary - N Changes (NULL, 0, NULL, valid, valid, valid, NULL
|
|
int Variation_6();
|
|
// @cmember Boundary - N Changes (NULL, 0, NULL, NULL, NULL, NULL, NULL
|
|
int Variation_7();
|
|
// @cmember Boundary - N Changes (NULL, 0, NULL, valid, valid,valid,valid,
|
|
int Variation_8();
|
|
// @cmember Boundary - Empty Rowset (NULL, 0, NULL, valid, valid,valid,valid,
|
|
int Variation_9();
|
|
// @cmember Empty
|
|
int Variation_10();
|
|
// @cmember Parameters - 3 hard deleted / 2 modified
|
|
int Variation_11();
|
|
// @cmember Parameters - 3 invalid / 2 inserted
|
|
int Variation_12();
|
|
// @cmember Parameters - 1 hard deleted / 1 invalid / 1 soft-del
|
|
int Variation_13();
|
|
// @cmember Parameters - 1 hard deleted / 1 invalid
|
|
int Variation_14();
|
|
// @cmember Parameters - 1 col with non-schema info
|
|
int Variation_15();
|
|
// @cmember Parameters - 3 col with metacolumn non-schema info
|
|
int Variation_16();
|
|
// @cmember Parameters - 2 inserted rows, no value specified / not nullable
|
|
int Variation_17();
|
|
// @cmember Empty
|
|
int Variation_18();
|
|
// @cmember Sequence - Update a non-updateable column
|
|
int Variation_19();
|
|
// @cmember Sequence - Delete a non-updateable column
|
|
int Variation_20();
|
|
// @cmember Sequence - Deferred only
|
|
int Variation_21();
|
|
// @cmember Sequence - Cache-Deferred only
|
|
int Variation_22();
|
|
// @cmember Sequence - Cache-Deferred / Deferred / Non-deferred col
|
|
int Variation_23();
|
|
// @cmember Empty
|
|
int Variation_24();
|
|
// @cmember Parameters - Duplicate hrow entries in the array
|
|
int Variation_25();
|
|
// @cmember Parameters - Fetch/Modify/Release
|
|
int Variation_26();
|
|
// @cmember Parameters - Fetch/Modify/don't Release
|
|
int Variation_27();
|
|
// @cmember Empty
|
|
int Variation_28();
|
|
// @cmember Accessor - BLOB / Long columns - SetPos
|
|
int Variation_29();
|
|
// @cmember Accessor - BLOB / Long columns - QBU
|
|
int Variation_30();
|
|
// @cmember Empty
|
|
int Variation_31();
|
|
// @cmember Related - Resync / GetOriginalData same data
|
|
int Variation_32();
|
|
// @cmember Related - ResynchRows
|
|
int Variation_33();
|
|
// @cmember Related - Modify / Resync
|
|
int Variation_34();
|
|
// @cmember Related - Modify / Resync / Undo
|
|
int Variation_35();
|
|
// @cmember Empty
|
|
int Variation_36();
|
|
// @cmember Properties - NONE
|
|
int Variation_37();
|
|
// @cmember Properties - OWNINSERT
|
|
int Variation_38();
|
|
// @cmember Properties - OWNINSERT & CANSCROLL
|
|
int Variation_39();
|
|
// @cmember Properties - OWNUPDATEDELETE
|
|
int Variation_40();
|
|
// @cmember Properties - OWNUPDATEDELETE & CANFETCH
|
|
int Variation_41();
|
|
// @cmember Properties - OTHERINSERT
|
|
int Variation_42();
|
|
// @cmember Properties - OTHERINSERT & CANSCROLL
|
|
int Variation_43();
|
|
// @cmember Properties - OTHERUPDATEDELETE
|
|
int Variation_44();
|
|
// @cmember Properties - OTHERUPDATEDELETE & CANSCROLL
|
|
int Variation_45();
|
|
// @cmember Properties - OWNUPDATEDELETE & OTHERINSERT
|
|
int Variation_46();
|
|
// @cmember Properties - OWNUPDATEDELETE & OTHERINSERT & CANFETCH
|
|
int Variation_47();
|
|
// @cmember Properties - OTHERUPDATEDELETE & OWNINSERT
|
|
int Variation_48();
|
|
// @cmember Properties - OTHERUPDATEDELETE & OWNINSERT & CANSCROLL
|
|
int Variation_49();
|
|
// @cmember Properties - verify property dependencies
|
|
int Variation_50();
|
|
// @cmember Empty
|
|
int Variation_51();
|
|
// @cmember Related - Qualified Table Name
|
|
int Variation_52();
|
|
// @cmember Empty
|
|
int Variation_53();
|
|
// @cmember Properties - MAXPENDINGCHANGEROWS
|
|
int Variation_54();
|
|
// @cmember Properties - CANHOLDROWS
|
|
int Variation_55();
|
|
// @cmember Properties - ~CANHOLDROWS
|
|
int Variation_56();
|
|
// @cmember Properties - BOOKMARKS
|
|
int Variation_57();
|
|
// @cmember Empty
|
|
int Variation_58();
|
|
// @cmember Transactions - Insert/Commit
|
|
int Variation_59();
|
|
// @cmember Transactions - Insert/Commit/Update
|
|
int Variation_60();
|
|
// @cmember Transactions - Modify/Update/Commit
|
|
int Variation_61();
|
|
// @cmember Transactions - Modify/Update/Commit/Undo
|
|
int Variation_62();
|
|
// @cmember Transactions - Delete/Update/Abort
|
|
int Variation_63();
|
|
// @cmember Transactions - Delete/Update/Abort/Undo
|
|
int Variation_64();
|
|
// @cmember Transactions - concurrency - DB_E_CONCURRENCYVILOATION
|
|
int Variation_65();
|
|
// @cmember Transactions - ABORTRETAINING
|
|
int Variation_66();
|
|
// @cmember Transactions - ~ABORTRETAINING
|
|
int Variation_67();
|
|
// @cmember Transactions - COMMITRETAINING
|
|
int Variation_68();
|
|
// @cmember Transactions - ~COMMITRETAINING
|
|
int Variation_69();
|
|
// @cmember Transactions - NOTENTRANT
|
|
int Variation_70();
|
|
// @cmember Empty
|
|
int Variation_71();
|
|
// @cmember Sequence - Insert/Modify/Delete a single row
|
|
int Variation_72();
|
|
// @cmember Sequence - Delete all rows/Undo 1/Modify 1/Update
|
|
int Variation_73();
|
|
// @cmember Sequence - 1 Row rowset/Delete row/Undo/Delete/Update/Undo/Update
|
|
int Variation_74();
|
|
// @cmember Sequence - Insert 3 rows/Undo all/Insert 4/Modify
|
|
int Variation_75();
|
|
// @cmember Empty
|
|
int Variation_76();
|
|
// @cmember Sequence - Call Update 3 times
|
|
int Variation_77();
|
|
// @cmember Sequence - Call Update on seperate columns
|
|
int Variation_78();
|
|
// @cmember Sequence - Update multilple rows, covering all types
|
|
int Variation_79();
|
|
// @cmember Sequence - Multiple Table Update
|
|
int Variation_80();
|
|
// }}
|
|
};
|
|
// {{ TCW_TESTCASE(TCUpdate)
|
|
#define THE_CLASS TCUpdate
|
|
BEG_TEST_CASE(TCUpdate, CRowsetUpdate, L"IRowsetUpdate::Update test case")
|
|
TEST_VARIATION(1, L"Boundary - No Changes [NULL, 0, NULL,NULL,NULL,NULL,NULL]")
|
|
TEST_VARIATION(2, L"Boundary - No Changes (NULL, 0, NULL, valid, valid, valid, valid")
|
|
TEST_VARIATION(3, L"Boundary - N Changes (NULL, N, valid, NULL, NULL, valid, valid")
|
|
TEST_VARIATION(4, L"Boundary - N Changes (invalid, N, NULL, valid, valid, valid, valid")
|
|
TEST_VARIATION(5, L"Boundary - N Changes (invalid, N, valid, valid, NULL, valid, valid")
|
|
TEST_VARIATION(6, L"Boundary - N Changes (NULL, 0, NULL, valid, valid, valid, NULL")
|
|
TEST_VARIATION(7, L"Boundary - N Changes (NULL, 0, NULL, NULL, NULL, NULL, NULL")
|
|
TEST_VARIATION(8, L"Boundary - N Changes (NULL, 0, NULL, valid, valid,valid,valid,")
|
|
TEST_VARIATION(9, L"Boundary - Empty Rowset (NULL, 0, NULL, valid, valid,valid,valid,")
|
|
TEST_VARIATION(10, L"Empty")
|
|
TEST_VARIATION(11, L"Parameters - 3 hard deleted / 2 modified")
|
|
TEST_VARIATION(12, L"Parameters - 3 invalid / 2 inserted")
|
|
TEST_VARIATION(13, L"Parameters - 1 hard deleted / 1 invalid / 1 soft-del")
|
|
TEST_VARIATION(14, L"Parameters - 1 hard deleted / 1 invalid")
|
|
TEST_VARIATION(15, L"Parameters - 1 col with non-schema info")
|
|
TEST_VARIATION(16, L"Parameters - 3 col with metacolumn non-schema info")
|
|
TEST_VARIATION(17, L"Parameters - 2 inserted rows, no value specified / not nullable")
|
|
TEST_VARIATION(18, L"Empty")
|
|
TEST_VARIATION(19, L"Sequence - Update a non-updateable column")
|
|
TEST_VARIATION(20, L"Sequence - Delete a non-updateable column")
|
|
TEST_VARIATION(21, L"Sequence - Deferred only")
|
|
TEST_VARIATION(22, L"Sequence - Cache-Deferred only")
|
|
TEST_VARIATION(23, L"Sequence - Cache-Deferred / Deferred / Non-deferred col")
|
|
TEST_VARIATION(24, L"Empty")
|
|
TEST_VARIATION(25, L"Parameters - Duplicate hrow entries in the array")
|
|
TEST_VARIATION(26, L"Parameters - Fetch/Modify/Release")
|
|
TEST_VARIATION(27, L"Parameters - Fetch/Modify/don't Release")
|
|
TEST_VARIATION(28, L"Empty")
|
|
TEST_VARIATION(29, L"Accessor - BLOB / Long columns - SetPos")
|
|
TEST_VARIATION(30, L"Accessor - BLOB / Long columns - QBU")
|
|
TEST_VARIATION(31, L"Empty")
|
|
TEST_VARIATION(32, L"Related - Resync / GetOriginalData same data")
|
|
TEST_VARIATION(33, L"Related - ResynchRows")
|
|
TEST_VARIATION(34, L"Related - Modify / Resync ")
|
|
TEST_VARIATION(35, L"Related - Modify / Resync / Undo")
|
|
TEST_VARIATION(36, L"Empty")
|
|
TEST_VARIATION(37, L"Properties - NONE")
|
|
TEST_VARIATION(38, L"Properties - OWNINSERT")
|
|
TEST_VARIATION(39, L"Properties - OWNINSERT & CANSCROLL")
|
|
TEST_VARIATION(40, L"Properties - OWNUPDATEDELETE")
|
|
TEST_VARIATION(41, L"Properties - OWNUPDATEDELETE & CANFETCH")
|
|
TEST_VARIATION(42, L"Properties - OTHERINSERT")
|
|
TEST_VARIATION(43, L"Properties - OTHERINSERT & CANSCROLL")
|
|
TEST_VARIATION(44, L"Properties - OTHERUPDATEDELETE")
|
|
TEST_VARIATION(45, L"Properties - OTHERUPDATEDELETE & CANSCROLL")
|
|
TEST_VARIATION(46, L"Properties - OWNUPDATEDELETE & OTHERINSERT")
|
|
TEST_VARIATION(47, L"Properties - OWNUPDATEDELETE & OTHERINSERT & CANFETCH")
|
|
TEST_VARIATION(48, L"Properties - OTHERUPDATEDELETE & OWNINSERT")
|
|
TEST_VARIATION(49, L"Properties - OTHERUPDATEDELETE & OWNINSERT & CANSCROLL")
|
|
TEST_VARIATION(50, L"Properties - verify property dependencies")
|
|
TEST_VARIATION(51, L"Empty")
|
|
TEST_VARIATION(52, L"Related - Qualified Table Name")
|
|
TEST_VARIATION(53, L"Empty")
|
|
TEST_VARIATION(54, L"Properties - MAXPENDINGCHANGEROWS")
|
|
TEST_VARIATION(55, L"Properties - CANHOLDROWS")
|
|
TEST_VARIATION(56, L"Properties - ~CANHOLDROWS")
|
|
TEST_VARIATION(57, L"Properties - BOOKMARKS")
|
|
TEST_VARIATION(58, L"Empty")
|
|
TEST_VARIATION(59, L"Transactions - Insert/Commit")
|
|
TEST_VARIATION(60, L"Transactions - Insert/Commit/Update")
|
|
TEST_VARIATION(61, L"Transactions - Modify/Update/Commit")
|
|
TEST_VARIATION(62, L"Transactions - Modify/Update/Commit/Undo")
|
|
TEST_VARIATION(63, L"Transactions - Delete/Update/Abort")
|
|
TEST_VARIATION(64, L"Transactions - Delete/Update/Abort/Undo")
|
|
TEST_VARIATION(65, L"Transactions - concurrency - DB_E_CONCURRENCYVILOATION")
|
|
TEST_VARIATION(66, L"Transactions - ABORTRETAINING")
|
|
TEST_VARIATION(67, L"Transactions - ~ABORTRETAINING")
|
|
TEST_VARIATION(68, L"Transactions - COMMITRETAINING")
|
|
TEST_VARIATION(69, L"Transactions - ~COMMITRETAINING")
|
|
TEST_VARIATION(70, L"Transactions - NOTENTRANT")
|
|
TEST_VARIATION(71, L"Empty")
|
|
TEST_VARIATION(72, L"Sequence - Insert/Modify/Delete a single row")
|
|
TEST_VARIATION(73, L"Sequence - Delete all rows/Undo 1/Modify 1/Update")
|
|
TEST_VARIATION(74, L"Sequence - 1 Row rowset/Delete row/Undo/Delete/Update/Undo/Update")
|
|
TEST_VARIATION(75, L"Sequence - Insert 3 rows/Undo all/Insert 4/Modify")
|
|
TEST_VARIATION(76, L"Empty")
|
|
TEST_VARIATION(77, L"Sequence - Call Update 3 times")
|
|
TEST_VARIATION(78, L"Sequence - Call Update on seperate columns")
|
|
TEST_VARIATION(79, L"Sequence - Update multilple rows, covering all types")
|
|
TEST_VARIATION(80, L"Sequence - Multiple Table Update")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCGetRowStatus)
|
|
//--------------------------------------------------------------------
|
|
// @class IRowsetUpdate::GetRowStatus
|
|
//
|
|
class TCGetRowStatus : public CRowsetUpdate {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCGetRowStatus,CRowsetUpdate);
|
|
// }}
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - Verify GetRowStatus alters row handles RefCount correctly
|
|
int Variation_1();
|
|
// @cmember Boundary - No Changes [invalid, 0, NULL, valid]
|
|
int Variation_2();
|
|
// @cmember Boundary - No Changes [NULL, 1, valid, NULL]
|
|
int Variation_3();
|
|
// @cmember Boundary - No Changes [NULL, 1, NULL, valid]
|
|
int Variation_4();
|
|
// @cmember Empty
|
|
int Variation_5();
|
|
// @cmember Empty
|
|
int Variation_6();
|
|
// @cmember Boundary - N Changes [NULL, 0, NULL, NULL]
|
|
int Variation_7();
|
|
// @cmember Boundary - N Changes [NULL, N, NULL, NULL]
|
|
int Variation_8();
|
|
// @cmember Boundary - N Changes [NULL, N, valid, valid]
|
|
int Variation_9();
|
|
// @cmember Boundary - Empty Rowset [NULL, N, valid, valid]
|
|
int Variation_10();
|
|
// @cmember Empty
|
|
int Variation_11();
|
|
// @cmember Empty
|
|
int Variation_12();
|
|
// @cmember Parameters - 3 hard deleted 2 modified
|
|
int Variation_13();
|
|
// @cmember Parameters - 3 invalid
|
|
int Variation_14();
|
|
// @cmember Parameters - 1 hard deleted 1 invalid 1 modified
|
|
int Variation_15();
|
|
// @cmember Empty
|
|
int Variation_16();
|
|
// @cmember Parameters - All types
|
|
int Variation_17();
|
|
// @cmember Parameters - All Unchanged
|
|
int Variation_18();
|
|
// @cmember Parameters - All Inserted
|
|
int Variation_19();
|
|
// @cmember Parameters - All Soft-Deleted
|
|
int Variation_20();
|
|
// @cmember Parameters - Insert/Modify
|
|
int Variation_21();
|
|
// @cmember Parameters - Modify Delete
|
|
int Variation_22();
|
|
// @cmember Parameters - Insert/Modify/Delete
|
|
int Variation_23();
|
|
// @cmember Empty
|
|
int Variation_24();
|
|
// @cmember Sequence - Insert/Delete/Modify - Update
|
|
int Variation_25();
|
|
// @cmember Sequence - Make all type changes - Undo half - Update
|
|
int Variation_26();
|
|
// @cmember Sequence - Change N rows, GetPendingRows, GetRowStatus
|
|
int Variation_27();
|
|
// @cmember Sequence - Call GetRowStatus 3 times
|
|
int Variation_28();
|
|
// }}
|
|
};
|
|
// {{ TCW_TESTCASE(TCGetRowStatus)
|
|
#define THE_CLASS TCGetRowStatus
|
|
BEG_TEST_CASE(TCGetRowStatus, CRowsetUpdate, L"IRowsetUpdate::GetRowStatus")
|
|
TEST_VARIATION(1, L"General - Verify GetRowStatus alters row handles RefCount correctly")
|
|
TEST_VARIATION(2, L"Boundary - No Changes [invalid, 0, NULL, valid]")
|
|
TEST_VARIATION(3, L"Boundary - No Changes [NULL, 1, valid, NULL]")
|
|
TEST_VARIATION(4, L"Boundary - No Changes [NULL, 1, NULL, valid]")
|
|
TEST_VARIATION(5, L"Empty")
|
|
TEST_VARIATION(6, L"Empty")
|
|
TEST_VARIATION(7, L"Boundary - N Changes [NULL, 0, NULL, NULL]")
|
|
TEST_VARIATION(8, L"Boundary - N Changes [NULL, N, NULL, NULL]")
|
|
TEST_VARIATION(9, L"Boundary - N Changes [NULL, N, valid, valid]")
|
|
TEST_VARIATION(10, L"Boundary - Empty Rowset [NULL, N, valid, valid]")
|
|
TEST_VARIATION(11, L"Empty")
|
|
TEST_VARIATION(12, L"Empty")
|
|
TEST_VARIATION(13, L"Parameters - 3 hard deleted 2 modified")
|
|
TEST_VARIATION(14, L"Parameters - 3 invalid")
|
|
TEST_VARIATION(15, L"Parameters - 1 hard deleted 1 invalid 1 modified")
|
|
TEST_VARIATION(16, L"Empty")
|
|
TEST_VARIATION(17, L"Parameters - All types")
|
|
TEST_VARIATION(18, L"Parameters - All Unchanged")
|
|
TEST_VARIATION(19, L"Parameters - All Inserted")
|
|
TEST_VARIATION(20, L"Parameters - All Soft-Deleted")
|
|
TEST_VARIATION(21, L"Parameters - Insert/Modify")
|
|
TEST_VARIATION(22, L"Parameters - Modify Delete")
|
|
TEST_VARIATION(23, L"Parameters - Insert/Modify/Delete")
|
|
TEST_VARIATION(24, L"Empty")
|
|
TEST_VARIATION(25, L"Sequence - Insert/Delete/Modify - Update")
|
|
TEST_VARIATION(26, L"Sequence - Make all type changes - Undo half - Update")
|
|
TEST_VARIATION(27, L"Sequence - Change N rows, GetPendingRows, GetRowStatus")
|
|
TEST_VARIATION(28, L"Sequence - Call GetRowStatus 3 times")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCExtendedErrors)
|
|
//--------------------------------------------------------------------
|
|
// @class Extended Errors
|
|
//
|
|
class TCExtendedErrors : public CRowsetUpdate {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCExtendedErrors,CRowsetUpdate);
|
|
// }}
|
|
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Valid GetOriginalData calls with previous error object existing.
|
|
int Variation_1();
|
|
// @cmember Invalid GetOriginalData calls with previous error object existing
|
|
int Variation_2();
|
|
// @cmember Invalid GetOriginalData calls with no previous error object existing
|
|
int Variation_3();
|
|
// @cmember Valid GetPendingRows calls with previous error object existing.
|
|
int Variation_4();
|
|
// @cmember Invalid GetPendingRows calls with previous error object existing
|
|
int Variation_5();
|
|
// @cmember Invalid GetPendingRows calls with no previous error object existing
|
|
int Variation_6();
|
|
// @cmember Valid GetRowStatus calls with previous error object existing.
|
|
int Variation_7();
|
|
// @cmember Invalid GetRowStatus calls with previous error object existing
|
|
int Variation_8();
|
|
// @cmember Invalid GetRowStatus calls with no previous error object existing
|
|
int Variation_9();
|
|
// @cmember Valid Undo calls with previous error object existing.
|
|
int Variation_10();
|
|
// @cmember Invalid Undo calls with previous error object existing
|
|
int Variation_11();
|
|
// @cmember Invalid Undo calls with no previous error object existing
|
|
int Variation_12();
|
|
// @cmember Valid Update calls with previous error object existing.
|
|
int Variation_13();
|
|
// @cmember Invalid Update calls with previous error object existing
|
|
int Variation_14();
|
|
// @cmember Invalid Update calls with no previous error object existing
|
|
int Variation_15();
|
|
// @cmember S_FALSE GetPendingRows call with no previous error object existing
|
|
int Variation_16();
|
|
// @cmember DB_E_DELETEDROW GetOriginalData call with no previous error object existing
|
|
int Variation_17();
|
|
// @cmember DB_E_BADACCESSORTYPE GetOriginal call with no previous error object existing
|
|
int Variation_18();
|
|
// }}
|
|
};
|
|
// {{ TCW_TESTCASE(TCExtendedErrors)
|
|
#define THE_CLASS TCExtendedErrors
|
|
BEG_TEST_CASE(TCExtendedErrors, CRowsetUpdate, L"Extended Errors")
|
|
TEST_VARIATION(1, L"Valid GetOriginalData calls with previous error object existing.")
|
|
TEST_VARIATION(2, L"Invalid GetOriginalData calls with previous error object existing")
|
|
TEST_VARIATION(3, L"Invalid GetOriginalData calls with no previous error object existing")
|
|
TEST_VARIATION(4, L"Valid GetPendingRows calls with previous error object existing.")
|
|
TEST_VARIATION(5, L"Invalid GetPendingRows calls with previous error object existing")
|
|
TEST_VARIATION(6, L"Invalid GetPendingRows calls with no previous error object existing")
|
|
TEST_VARIATION(7, L"Valid GetRowStatus calls with previous error object existing.")
|
|
TEST_VARIATION(8, L"Invalid GetRowStatus calls with previous error object existing")
|
|
TEST_VARIATION(9, L"Invalid GetRowStatus calls with no previous error object existing")
|
|
TEST_VARIATION(10, L"Valid Undo calls with previous error object existing.")
|
|
TEST_VARIATION(11, L"Invalid Undo calls with previous error object existing")
|
|
TEST_VARIATION(12, L"Invalid Undo calls with no previous error object existing")
|
|
TEST_VARIATION(13, L"Valid Update calls with previous error object existing.")
|
|
TEST_VARIATION(14, L"Invalid Update calls with previous error object existing")
|
|
TEST_VARIATION(15, L"Invalid Update calls with no previous error object existing")
|
|
TEST_VARIATION(16, L"S_FALSE GetPendingRows call with no previous error object existing")
|
|
TEST_VARIATION(17, L"DB_E_DELETEDROW GetOriginalData call with no previous error object existing")
|
|
TEST_VARIATION(18, L"DB_E_BADACCESSORTYPE GetOriginal call with no previous error object existing")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCZombie)
|
|
//--------------------------------------------------------------------
|
|
// @class Zombie testing of IRowsetUpdate
|
|
//
|
|
class TCZombie : public CTransaction {
|
|
private:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCZombie,CTransaction);
|
|
// }}
|
|
|
|
ULONG m_cPropSets;
|
|
DBPROPSET* m_rgPropSets;
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Zombie - ABORT with fRetaining == TRUE
|
|
int Variation_1();
|
|
// @cmember Zombie - ABORT with fRetaining == FALSE
|
|
int Variation_2();
|
|
// @cmember Zombie - COMMIT with fRetaining == TRUE
|
|
int Variation_3();
|
|
// @cmember Zombie - COMMIT with fRetaining == TRUE
|
|
int Variation_4();
|
|
// }}
|
|
};
|
|
// {{ TCW_TESTCASE(TCZombie)
|
|
#define THE_CLASS TCZombie
|
|
BEG_TEST_CASE(TCZombie, CTransaction, L"Zombie testing of IRowsetUpdate")
|
|
TEST_VARIATION(1, L"Zombie - ABORT with fRetaining == TRUE")
|
|
TEST_VARIATION(2, L"Zombie - ABORT with fRetaining == FALSE")
|
|
TEST_VARIATION(3, L"Zombie - COMMIT with fRetaining == TRUE")
|
|
TEST_VARIATION(4, L"Zombie - COMMIT with fRetaining == TRUE")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// }} END_DECLARE_TEST_CASES();
|
|
|
|
// {{ TCW_TESTMODULE(ThisModule)
|
|
TEST_MODULE(7, ThisModule, gwszModuleDescrip)
|
|
TEST_CASE(1, TCGetOriginalRows)
|
|
TEST_CASE(2, TCGetPendingRows)
|
|
TEST_CASE(3, TCUndo)
|
|
TEST_CASE(4, TCUpdate)
|
|
TEST_CASE(5, TCGetRowStatus)
|
|
TEST_CASE(6, TCExtendedErrors)
|
|
TEST_CASE(7, TCZombie)
|
|
END_TEST_MODULE()
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCGetOriginalRows)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCGetOriginalRows - IRowsetUpdate::GetOriginalRows test case
|
|
//| Created: 03/29/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetOriginalRows::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CRowsetUpdate::Init())
|
|
// }}
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
return TEST_FAIL;
|
|
}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - IID_IRowsetUpdate on a read-only rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_1()
|
|
{
|
|
TBEGIN
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate ReadOnlyRowset;
|
|
|
|
//Try to ask for IID_IRowsetUpdate on a readonly rowset
|
|
TESTC_PROVIDER(ReadOnlyRowset.CreateRowset(SELECT_COUNT)==S_OK);
|
|
|
|
//Now that IRowsetUpdate is allowed on a read-only rowset, verify
|
|
//DBPROP_COLUMNRESTICT is VARIANT_TRUE
|
|
TESTC_PROVIDER(ReadOnlyRowset.GetProperty(DBPROP_COLUMNRESTRICT));
|
|
|
|
//Also Verify that we can't make any changes to this rowset
|
|
TESTC_(ReadOnlyRowset.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
TESTC_(ReadOnlyRowset.DeleteRow(hRow),S_OK);
|
|
TESTC_(ReadOnlyRowset.UpdateRow(ONE_ROW,&hRow,NULL,NULL,&rgRowStatus),DB_E_ERRORSOCCURRED);
|
|
|
|
//Verify not updatable
|
|
TESTC(rgRowStatus != NULL);
|
|
|
|
//PERMISSIONDENIED should only be returned if ROWRESTRICT is on
|
|
if(ReadOnlyRowset.GetProperty(DBPROP_ROWRESTRICT))
|
|
{
|
|
TESTC(rgRowStatus[0] == DBROWSTATUS_E_PERMISSIONDENIED);
|
|
}
|
|
else
|
|
{
|
|
TESTC(rgRowStatus[0] == DBROWSTATUS_E_INTEGRITYVIOLATION);
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
ReadOnlyRowset.ReleaseRows(hRow);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - IID_IRowsetUpdate on a read-only rowset, created with OuterJoin
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_2()
|
|
{
|
|
TBEGIN
|
|
IDBSchemaRowset* pIDBSchemaRowset = NULL;
|
|
IUnknown* pIUnknown = NULL;
|
|
|
|
CRowset Rowset1;
|
|
Rowset1.SetProperty(DBPROP_IRowsetChange);
|
|
|
|
CRowset Rowset2;
|
|
Rowset2.SetProperty(DBPROP_IRowsetUpdate);
|
|
|
|
//Obtain IDBSchemaRowset interface
|
|
HRESULT hr = QI(pISession(), IID_IDBSchemaRowset,(void**)&pIDBSchemaRowset);
|
|
|
|
//Not all providers will support IDBSchemaRowset
|
|
TESTC_PROVIDER(hr==S_OK);
|
|
|
|
//Try to ask for DBPROP_IRowsetChange on a read-only schema rowset
|
|
TESTC_(pIDBSchemaRowset->GetRowset(NULL,DBSCHEMA_TABLES,0,NULL,IID_IRowset,Rowset1.m_cPropSets,Rowset1.m_rgPropSets,&pIUnknown),DB_E_ERRORSOCCURRED);
|
|
TESTC_(pIDBSchemaRowset->GetRowset(NULL,DBSCHEMA_TABLES,0,NULL,IID_IRowsetChange,0,NULL,&pIUnknown),E_NOINTERFACE);
|
|
|
|
//Try to ask for DBPROP_IRowsetUpdate on a read-only schema rowset
|
|
TESTC_(pIDBSchemaRowset->GetRowset(NULL,DBSCHEMA_TABLES,0,NULL,IID_IRowset,Rowset2.m_cPropSets,Rowset2.m_rgPropSets,&pIUnknown),DB_E_ERRORSOCCURRED);
|
|
TESTC_(pIDBSchemaRowset->GetRowset(NULL,DBSCHEMA_TABLES,0,NULL,IID_IRowsetUpdate,0,NULL,&pIUnknown),E_NOINTERFACE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBSchemaRowset);
|
|
SAFE_RELEASE(pIUnknown);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - IID_IRowsetChange implicitly set on IID_IRowsetUpdate
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_3()
|
|
{
|
|
TBEGIN
|
|
CRowset RowsetA;
|
|
|
|
//Set Properties
|
|
RowsetA.SetProperty(DBPROP_IRowsetUpdate);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Just as a sanity check, make sure IID_IRowseUpdate is still set
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_IRowsetUpdate));
|
|
|
|
//Verify IID_IRowsetChange is implicitly set
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_IRowsetChange));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - IID_IRowsetUpdate is not exposed on IRowsetChange
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_4()
|
|
{
|
|
TBEGIN
|
|
CRowsetChange RowsetChange;
|
|
TESTC_PROVIDER(RowsetChange.CreateRowset()==S_OK);
|
|
|
|
//Just as a sanity check, make sure IID_IRowseChange is still set
|
|
TESTC_PROVIDER(RowsetChange.GetProperty(DBPROP_IRowsetChange));
|
|
|
|
//Verify IID_IRowsetUpdate is not implicitly set
|
|
TESTC_PROVIDER(!(RowsetChange.GetProperty(DBPROP_IRowsetUpdate)));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - IID_IRowsetLocate exposed on IRowsetUpdate
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_5()
|
|
{
|
|
TBEGIN
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_IRowsetLocate)==S_OK);
|
|
|
|
//Just as a sanity check, make sure properties are still set
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_IRowsetUpdate));
|
|
|
|
//Verify IID_IRowsetLocate is implicitly set
|
|
if(SupportedProperty(DBPROP_IRowsetLocate, DBPROPSET_ROWSET))
|
|
TESTC(RowsetA.GetProperty(DBPROP_IRowsetLocate));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - QueryI(invalid, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_6()
|
|
{
|
|
TBEGIN
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//QI for a non-rowset Interface
|
|
TESTC_(QI(RowsetA.pIRowsetUpdate(),IID_IConnectionPoint),E_NOINTERFACE);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - QueryI(valid, NULL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_7()
|
|
{
|
|
TBEGIN
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->QueryInterface(IID_IRowsetUpdate, NULL),E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - QueryI(IID_IRowsetUpdate, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_8()
|
|
{
|
|
TBEGIN
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(QI(RowsetA.pIRowsetUpdate(),IID_IRowsetUpdate),S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - QueryI(IID_IRowsetChange, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_9()
|
|
{
|
|
TBEGIN
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(QI(RowsetA.pIRowsetUpdate(),IID_IRowsetChange),S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - IRowsetChange->QueryI(IID_IRowsetUpdate, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_10()
|
|
{
|
|
TBEGIN
|
|
//Create a IRowsetChange
|
|
CRowsetChange RowsetChange;
|
|
TESTC_PROVIDER(RowsetChange.CreateRowset(DBPROP_IRowsetChange)==S_OK);
|
|
|
|
// IRowsetChange->QI(IID_IRowsetUpdate)
|
|
TESTC_(QI(RowsetChange.pIRowsetChange(),IID_IRowsetUpdate),E_NOINTERFACE);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Verify AddRef / Release
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_11()
|
|
{
|
|
TBEGIN
|
|
ULONG cOrgRefCount;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the current reference count
|
|
cOrgRefCount = GetRefCount(RowsetA.pIRowsetUpdate());
|
|
|
|
//Increment ref count a few times
|
|
RowsetA.pIRowsetUpdate()->AddRef();
|
|
RowsetA.pIRowsetUpdate()->AddRef();
|
|
RowsetA.pIRowsetUpdate()->AddRef();
|
|
|
|
//Release a couple of times
|
|
RowsetA.pIRowsetUpdate()->Release();
|
|
RowsetA.pIRowsetUpdate()->Release();
|
|
|
|
//Addref
|
|
RowsetA.pIRowsetUpdate()->AddRef();
|
|
|
|
//Release
|
|
RowsetA.pIRowsetUpdate()->Release();
|
|
RowsetA.pIRowsetUpdate()->Release();
|
|
|
|
TESTC(GetRefCount(RowsetA.pIRowsetUpdate())==cOrgRefCount);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Verify RefCount or row handles
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_12()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
void* rgpOriginalData[NROWS] = {NULL,NULL,NULL};
|
|
|
|
ULONG i;
|
|
ULONG rgBeforeRefCounts[NROWS] = {0,0,0};
|
|
ULONG rgAfterRefCounts[NROWS] = {0,0,0};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Get the current ref count for all row handles, before the call
|
|
TESTC_(RowsetA()->AddRefRows(NROWS,rghRow,rgBeforeRefCounts,NULL),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(NROWS,rghRow),S_OK);
|
|
|
|
//Call GetOriginalData on the above rows
|
|
TESTC_(RowsetA.GetOriginalData(NROWS, rghRow, rgpOriginalData),S_OK);
|
|
|
|
//Get the current ref count for all row handles, after the call
|
|
TESTC_(RowsetA()->AddRefRows(NROWS,rghRow,rgAfterRefCounts,NULL),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(NROWS,rghRow),S_OK);
|
|
|
|
//Verify the refcount of the row handles have not increased
|
|
for(i=0; i<NROWS; i++)
|
|
COMPC(rgBeforeRefCounts[i],rgAfterRefCounts[i])
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
PROVIDER_FREE2(NROWS, rgpOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - [NULL Accessor]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_13()
|
|
{
|
|
TBEGIN
|
|
HACCESSOR hNullAccessor = DB_NULL_HACCESSOR;
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
HROW hRow = DB_NULL_HROW;
|
|
void* pData = INVALID(void*);
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Create a NULL Accessor
|
|
TESTC_(RowsetA.pIAccessor()->CreateAccessor(DBACCESSOR_ROWDATA,0,NULL,0,&hNullAccessor,NULL),S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,hNullAccessor,pData),S_OK);
|
|
TESTC(pData==INVALID(void*));
|
|
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(INVALID(HACCESSOR),NULL),DB_E_BADACCESSORHANDLE);
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(DB_NULL_HACCESSOR,NULL),DB_E_BADACCESSORHANDLE);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseAccessor(hNullAccessor);
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - [PASSBYREF NULL Accessor]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_14()
|
|
{
|
|
TBEGIN
|
|
HACCESSOR hNullAccessor = DB_NULL_HACCESSOR;
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
HROW hRow = DB_NULL_HROW;
|
|
void* pData = INVALID(void*);
|
|
BOOL fByrefAccessorSupported = FALSE;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Create a NULL BYREF Accessor (if supported)
|
|
if(RowsetA.GetProperty(DBPROP_BYREFACCESSORS))
|
|
{
|
|
TESTC_(RowsetA.pIAccessor()->CreateAccessor(DBACCESSOR_ROWDATA | DBACCESSOR_PASSBYREF ,0,NULL,0,&hNullAccessor,NULL),S_OK);
|
|
}
|
|
//Otherwsie just a NULL Accessor is fine
|
|
else
|
|
{
|
|
TESTC_(RowsetA.pIAccessor()->CreateAccessor(DBACCESSOR_ROWDATA ,0,NULL,0,&hNullAccessor,NULL),S_OK);
|
|
}
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,hNullAccessor,pData),S_OK);
|
|
TESTC(pData==INVALID(void*));
|
|
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(hNullAccessor,NULL),S_OK);
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(hAccessor,NULL),DB_E_BADACCESSORHANDLE);
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(INVALID(HACCESSOR),NULL),DB_E_BADACCESSORHANDLE);
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(DB_NULL_HACCESSOR,NULL),DB_E_BADACCESSORHANDLE);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseAccessor(hNullAccessor);
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - [valid, valid, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_15()
|
|
{
|
|
TBEGIN
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Get the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Call GetOriginalData with NULL pDdata
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,NULL),E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - [DB_INVALID_ROW, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_16()
|
|
{
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Call GetOriginalData with invalid row - should fail gracefully
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(DB_NULL_HROW,RowsetA.m_hAccessor,RowsetA.m_pData),DB_E_BADROWHANDLE);
|
|
TESTC(RowsetA.m_pData!=NULL) //provider shouldn't touch my alloced buffer;
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - [valid, DB_NULL_HACCESSOR, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_17()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Should be able to pass DB_NUL_HROW to release rows
|
|
TESTC_(RowsetA.ReleaseRows(ONE_ROW,&hRow),DB_E_ERRORSOCCURRED);
|
|
|
|
//Get the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Call GetOriginalData with a NULL Accessor
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,DB_NULL_HACCESSOR,RowsetA.m_pData),DB_E_BADACCESSORHANDLE);
|
|
TESTC(RowsetA.m_pData!=NULL) //provider shouldn't touch my alloced buffer;
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Call GetOriginalData before any other method
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_18()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Get the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//GetOriginalData, before any other modifying methods
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),S_OK);
|
|
TESTC(RowsetA.m_pData!=NULL) //provider shouldn't touch my alloced buffer;
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_19()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Hard deleted row
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_20()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Hard-delete the row
|
|
TESTC_(RowsetA.HardDeleteRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the hard deleted row
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),DB_E_DELETEDROW);
|
|
TESTC(RowsetA.m_pData!=NULL) //provider shouldn't touch my alloced buffer;
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Soft Deleted row, No update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_21()
|
|
{
|
|
void* pOriginalData = NULL;
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(hRow, &pOriginalData),S_OK);
|
|
|
|
//Soft-delete the row
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the soft deleted row
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),S_OK);
|
|
|
|
//Compare with the orginal data, should match
|
|
TESTC(RowsetA.CompareRowData(pOriginalData,RowsetA.m_pData));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Newly inserted row, No update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_22()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Soft-Insert the row
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the soft inserted row
|
|
//This may produce DB_S_ERRORSOCCURRED since if the driver has non-NULL
|
|
//columns, Some providers cannot return ISNULL, and has no idea what valid
|
|
//defaults would be, so DBSTATUS_E_UNAVAILABLE will be returned for those
|
|
//columns
|
|
TEST3C_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),S_OK,DB_S_ERRORSOCCURRED,DB_E_ERRORSOCCURRED);
|
|
|
|
//GetOriginalData should return defaults, therefore it should not match
|
|
TESTC(!RowsetA.CompareRowData(hRow,RowsetA.m_pData));
|
|
|
|
//Compare with defaults
|
|
TESTC(RowsetA.CompareWithDefaults(RowsetA.m_pData));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//--------------------------------------------------------------------
|
|
// @mfunc Parameters - Newly inserted row - NULL Accessor, No update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_23()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
HACCESSOR hAccessor = NULL;
|
|
void* pData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Create NULL Accessor
|
|
TESTC_(RowsetA.pIAccessor()->CreateAccessor(DBACCESSOR_ROWDATA, 0, NULL, 0, &hAccessor, NULL),S_OK);
|
|
|
|
//Soft-Insert the row (using NULL Accessor)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->InsertRow(NULL, hAccessor, NULL, &hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the soft inserted row
|
|
//This may produce DB_S_ERRORSOCCURRED since if the driver has non-NULL
|
|
//columns, Some providers cannot return ISNULL, and has no idea what valid
|
|
//defaults would be, so DBSTATUS_E_UNAVAILABLE will be returned for those
|
|
//columns
|
|
TEST3C_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),S_OK,DB_S_ERRORSOCCURRED,DB_E_ERRORSOCCURRED);
|
|
|
|
//Get the Data
|
|
TEST3C_(RowsetA.GetRowData(hRow, &pData),S_OK,DB_S_ERRORSOCCURRED,DB_E_ERRORSOCCURRED);
|
|
|
|
//Compare with defaults
|
|
TESTC(RowsetA.CompareWithDefaults(RowsetA.m_pData));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - A modified row, No update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_24()
|
|
{
|
|
void* pOriginalData = NULL;
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Save the orginal data
|
|
TESTC_(RowsetA.GetRowData(hRow, &pOriginalData),S_OK);
|
|
|
|
//Modify the row
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the modified row
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),S_OK);
|
|
|
|
//Compare data with orginal data, should match
|
|
TESTC(RowsetA.CompareRowData(pOriginalData,RowsetA.m_pData));
|
|
|
|
//Compare data with modified data, should not match
|
|
TESTC(!RowsetA.CompareRowData(hRow,RowsetA.m_pData));
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - An inserted, modified row
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_25()
|
|
{
|
|
void* pModifiedData = NULL;
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
|
|
//Modify the row
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
|
|
//Save the modified data
|
|
TESTC_(RowsetA.GetRowData(hRow, &pModifiedData),S_OK);
|
|
|
|
//Call GetOriginalData on the modified row
|
|
TEST3C_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),S_OK,DB_S_ERRORSOCCURRED,DB_E_ERRORSOCCURRED);
|
|
|
|
//Compare data with modified data, should not match
|
|
TESTC(!RowsetA.CompareRowData(pModifiedData,RowsetA.m_pData));
|
|
|
|
//Compare data with defaults, should match
|
|
TESTC(RowsetA.CompareWithDefaults(RowsetA.m_pData));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pModifiedData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - A newly inserted row, update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_26()
|
|
{
|
|
TBEGIN
|
|
HROW hRow = DB_NULL_HROW;
|
|
HACCESSOR hAccessor = NULL;
|
|
void* pOriginalData = NULL;
|
|
void* pData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Soft-Insert the row
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
|
|
//Save the OriginalData
|
|
TEST3C_(RowsetA.GetOriginalData(hRow, &pOriginalData),S_OK,DB_S_ERRORSOCCURRED,DB_E_ERRORSOCCURRED);
|
|
|
|
//Save the Data
|
|
TESTC_(RowsetA.GetRowData(hRow, &pData),S_OK);
|
|
|
|
//Update the row - (Hard Insert)
|
|
TESTC_(RowsetA.UpdateRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the updated row
|
|
TESTC_(RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),S_OK);
|
|
|
|
//Compare data with original data, should not match (updated)
|
|
TESTC(!RowsetA.CompareRowData(pOriginalData, RowsetA.m_pData));
|
|
|
|
//Compare data with row data, should match (updated)
|
|
TESTC(RowsetA.CompareRowData(pData, RowsetA.m_pData));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//--------------------------------------------------------------------
|
|
// @mfunc Parameters - A newly inserted row - NULL Accessor, update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_27()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr;
|
|
|
|
HROW hRow = DB_NULL_HROW;
|
|
HACCESSOR hAccessor = NULL;
|
|
void* pData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_SERVERDATAONINSERT);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
pData = PROVIDER_ALLOC(RowsetA.m_cRowSize*sizeof(void*));
|
|
|
|
//Create NULL Accessor
|
|
TESTC_(RowsetA.pIAccessor()->CreateAccessor(DBACCESSOR_ROWDATA, 0, NULL, 0, &hAccessor, NULL),S_OK);
|
|
|
|
//Soft-Insert the row (using NULL Accessor)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->InsertRow(NULL, hAccessor, NULL, &hRow),S_OK);
|
|
|
|
//This may produce DB_E_ERRORSOCCURRED since if the table has non-NULL
|
|
//columns, the driver may fail to insert the row, since I have bound no values
|
|
hr = RowsetA.UpdateRow(hRow);
|
|
TESTC(hr==S_OK || hr==DB_E_ERRORSOCCURRED);
|
|
|
|
//Call GetOriginalData on the soft inserted row
|
|
//Since there really is no "OrginalData" on a newly inserted row
|
|
//that hasn't been updated yet, the provider should return defaults
|
|
if(hr == S_OK)
|
|
{
|
|
//Note: Since the update succeeded, the provider used NULLs for nullable columns
|
|
//and Defaults for all columns that were non-nullable that had defaults. Weither they return
|
|
//the defaults (ie: make a roundtrip to obtain the defaults inserted), is dependent upon the
|
|
//DBPROP_SERVERDATAONINSERT property. If this is not supported, then we have to allow
|
|
//errors returned since the defaults may not have been brought back from the server...
|
|
if(SettableProperty(DBPROP_SERVERDATAONINSERT, DBPROPSET_ROWSET))
|
|
{
|
|
TESTC_(hr = RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),S_OK);
|
|
}
|
|
else
|
|
{
|
|
TEST3C_(hr = RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),S_OK,DB_S_ERRORSOCCURRED,DB_E_ERRORSOCCURRED);
|
|
}
|
|
|
|
//GetData for row in the rowset (should return the same result as GetOriginalData)
|
|
TESTC_(RowsetA.pIRowset()->GetData(hRow,RowsetA.m_hAccessor,pData), hr);
|
|
|
|
//Both GetOriginalData and GetData should match...
|
|
//The row was successfully inserted, so now there is no pending insert
|
|
TESTC(RowsetA.CompareRowData(RowsetA.m_pData, pData));
|
|
}
|
|
else
|
|
{
|
|
//This may produce DB_S_ERRORSOCCURRED since if the driver has non-NULL
|
|
//columns, some providers cannot return ISNULL, and has no idea what valid
|
|
//defaults would be, so DBSTATUS_E_UNAVAILABLE will be returned for those columns
|
|
TEST3C_(RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),S_OK,DB_S_ERRORSOCCURRED,DB_E_ERRORSOCCURRED);
|
|
|
|
//GetData for row in the rowset
|
|
TEST3C_(RowsetA.pIRowset()->GetData(hRow,RowsetA.m_hAccessor,pData),S_OK,DB_S_ERRORSOCCURRED,DB_E_ERRORSOCCURRED);
|
|
|
|
//Compare data with defaults, should match
|
|
TESTC(RowsetA.CompareWithDefaults(RowsetA.m_pData));
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - A modified row, update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_28()
|
|
{
|
|
void* pOriginalData = NULL;
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(hRow, &pOriginalData),S_OK);
|
|
|
|
//Hard-Modify the row
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
TESTC_(RowsetA.UpdateRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the modified row
|
|
TESTC_(RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),S_OK);
|
|
|
|
//Compare data with orginal data, should not equal, updated was performed
|
|
TESTC(!RowsetA.CompareRowData(pOriginalData,RowsetA.m_pData));
|
|
|
|
//Compare data with modified data, should be equal, update was performed
|
|
TESTC(RowsetA.CompareRowData(hRow,RowsetA.m_pData));
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - An inserted/modified row, update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_29()
|
|
{
|
|
void* pOriginalData = NULL;
|
|
void* pModifiedData = NULL;
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
|
|
//Save the OriginalData
|
|
TESTC_(RowsetA.GetRowData(hRow, &pOriginalData),S_OK);
|
|
|
|
//Modify the row
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
|
|
//Save the modified data
|
|
TESTC_(RowsetA.GetRowData(hRow, &pModifiedData),S_OK);
|
|
|
|
//Update the row
|
|
TESTC_(RowsetA.UpdateRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the updated row
|
|
TESTC_(RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),S_OK);
|
|
|
|
//Compare data with modified data, should match, (updated)
|
|
TESTC(RowsetA.CompareRowData(pModifiedData,RowsetA.m_pData));
|
|
|
|
//Compare data with original data, should not match (updated)
|
|
TESTC(!RowsetA.CompareRowData(pOriginalData,RowsetA.m_pData));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pModifiedData);
|
|
PROVIDER_FREE(pOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Insert/Modify/Delete all rows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_30()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
DBCOUNTITEM i,cRows = NROWS;
|
|
|
|
//Create a rowset with no rows
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_CANHOLDROWS);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, g_p1RowTable)==S_OK);
|
|
cRows = RowsetA.GetMaxPendingRows();
|
|
if(cRows==0 || cRows>NROWS)
|
|
cRows = NROWS;
|
|
|
|
//Now insert all rows
|
|
TESTC_(RowsetA.InsertRow(cRows, rghRow),S_OK);
|
|
|
|
//Now modify all rows
|
|
TESTC_(RowsetA.ModifyRow(cRows, rghRow),S_OK);
|
|
|
|
//Now delete all rows
|
|
TESTC_(RowsetA.DeleteRow(cRows, rghRow),S_OK);
|
|
|
|
//Now call GetOriginalData
|
|
for(i=0; i<cRows; i++)
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[i], &RowsetA.m_pData),DB_E_DELETEDROW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_31()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_32()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_33()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_34()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_35()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_36()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_37()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(38)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Accessor - BLOB / Long columns - SetPos
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_38()
|
|
{
|
|
TBEGIN
|
|
TRETURN //TODO need to work on blob support once supported
|
|
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
HROW hNewRow = DB_NULL_HROW;
|
|
DBLENGTH cRowSize = 0;
|
|
|
|
void* pInsertData = NULL;
|
|
void* pModifyData = NULL;
|
|
|
|
void* pData1 = NULL;
|
|
void* pData2 = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetLocate);
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Create Accessor binding BLOB/Long data (last param TRUE)
|
|
TESTC_(GetAccessorAndBindings(RowsetA(),DBACCESSOR_ROWDATA,&hAccessor,
|
|
NULL,NULL,&cRowSize,DBPART_ALL,UPDATEABLE_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_NOTPARAM, BLOB_LONG), S_OK);
|
|
|
|
//Alloc buffers
|
|
TESTC(RowsetA.MakeRowData(&pInsertData,hAccessor));
|
|
TESTC(RowsetA.MakeRowData(&pModifyData,hAccessor));
|
|
pData1 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
pData2 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
|
|
//Get Rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Get the Data
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData1),S_OK);
|
|
|
|
//Insert a row (BLOB data)
|
|
TESTC_(RowsetA.pIRowsetChange()->InsertRow(NULL,hAccessor, pInsertData, &hNewRow),S_OK);
|
|
//Modify a row (BLOB data)
|
|
TESTC_(RowsetA.pIRowsetChange()->SetData(rghRow[ROW_ONE],hAccessor, pModifyData),S_OK);
|
|
//Delete a row (BLOB data)
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//GetOrginalData should produce the orginal results
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(rghRow[ROW_ONE], hAccessor, pData2),S_OK);
|
|
TESTC(RowsetA.CompareRowData(pData1, pData2, hAccessor));
|
|
|
|
CLEANUP:
|
|
//Free Data
|
|
RowsetA.ReleaseRowData(pInsertData,hAccessor);
|
|
RowsetA.ReleaseRowData(pModifyData,hAccessor);
|
|
|
|
//Release the Accesssor
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
|
|
PROVIDER_FREE(pData1);
|
|
PROVIDER_FREE(pData2);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(39)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Accessor - BLOB / Long columns - QBU
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_39()
|
|
{
|
|
TBEGIN
|
|
TRETURN //TODO need to work on blob support once supported
|
|
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
HROW hNewRow = DB_NULL_HROW;
|
|
DBLENGTH cRowSize = 0;
|
|
|
|
void* pInsertData = NULL;
|
|
void* pModifyData = NULL;
|
|
|
|
void* pData1 = NULL;
|
|
void* pData2 = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetLocate);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Create Accessor binding BLOB/Long data (last param TRUE)
|
|
TESTC_(GetAccessorAndBindings(RowsetA(),DBACCESSOR_ROWDATA,&hAccessor,
|
|
NULL,NULL,&cRowSize,DBPART_ALL,UPDATEABLE_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_NOTPARAM, BLOB_LONG), S_OK);
|
|
|
|
//Alloc buffers
|
|
TESTC(RowsetA.MakeRowData(&pInsertData,hAccessor));
|
|
TESTC(RowsetA.MakeRowData(&pModifyData,hAccessor));
|
|
pData1 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
pData2 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
|
|
//Get Rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Get the Data
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData1),S_OK);
|
|
|
|
//Insert a row (BLOB data)
|
|
TESTC_(RowsetA.pIRowsetChange()->InsertRow(NULL,hAccessor, pInsertData, &hNewRow),S_OK);
|
|
//Modify a row (BLOB data)
|
|
TESTC_(RowsetA.pIRowsetChange()->SetData(rghRow[ROW_ONE],hAccessor, pModifyData),S_OK);
|
|
//Delete a row (BLOB data)
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//GetOrginalData should produce the orginal results
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(rghRow[ROW_ONE], hAccessor, pData2),S_OK);
|
|
TESTC(RowsetA.CompareRowData(pData1, pData2, hAccessor));
|
|
|
|
CLEANUP:
|
|
//Free Data
|
|
RowsetA.ReleaseRowData(pInsertData,hAccessor);
|
|
RowsetA.ReleaseRowData(pModifyData,hAccessor);
|
|
|
|
//Release the Accesssor
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
|
|
PROVIDER_FREE(pData1);
|
|
PROVIDER_FREE(pData2);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(40)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_40()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(41)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DB_E_BADACCESSORTYPE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_41()
|
|
{
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
HROW hRow = DB_NULL_HROW;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Create the rowset
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateCommand()==S_OK);
|
|
|
|
//Create an invalid Accessor for use with GetOriginalData
|
|
//Must be done on the CommandObject, ParameterAccessors are not allowed
|
|
//to be created on the RowsetObject
|
|
TEST2C_(hr = GetAccessorAndBindings(RowsetA.pICommand(),DBACCESSOR_PARAMETERDATA,&hAccessor,
|
|
NULL,NULL,NULL,DBPART_ALL,ALL_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_INPUT), S_OK, DB_E_BADACCESSORFLAGS);
|
|
|
|
if(hr == S_OK)
|
|
{
|
|
//Now that we have the Accessor Created, now create the rowset
|
|
//Must be a command query, since the accessor was created on the command
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(SELECT_REVCOLLIST)==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
//Call GetOriginalData with an invalid accessor type
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,hAccessor,RowsetA.m_pData),DB_E_BADACCESSORTYPE);
|
|
TESTC(RowsetA.m_pData!=NULL);
|
|
}
|
|
else
|
|
{
|
|
//Make sure the provider doesn't support parameters (validated immediately)
|
|
TESTC_(QI(RowsetA.pICommand(), IID_ICommandWithParameters), E_NOINTERFACE);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(42)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DB_E_SEC_E_PERMISSIONDENIED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_42()
|
|
{
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
HROW hRow = DB_NULL_HROW;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Create the rowset
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateCommand()==S_OK);
|
|
|
|
//Create an invalid Accessor for use with GetOriginalData
|
|
//Must be done on the CommandObject, ParameterAccessors are not allowed
|
|
//to be created on the RowsetObject
|
|
TEST2C_(hr = GetAccessorAndBindings(RowsetA.pICommand(),DBACCESSOR_PARAMETERDATA,&hAccessor,
|
|
NULL,NULL,NULL,DBPART_ALL,ALL_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_INPUT), S_OK, DB_E_BADACCESSORFLAGS);
|
|
|
|
if(hr == S_OK)
|
|
{
|
|
//Now that we have the Accessor Created, now create the rowset
|
|
//Must be a command query, since the accessor was created on the command
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(SELECT_REVCOLLIST)==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
//Call GetOriginalData with an invalid accessor type
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,hAccessor,RowsetA.m_pData),DB_E_BADACCESSORTYPE);
|
|
TESTC(RowsetA.m_pData!=NULL);
|
|
}
|
|
else
|
|
{
|
|
//Make sure the provider doesn't support parameters (validated immediately)
|
|
TESTC_(QI(RowsetA.pICommand(), IID_ICommandWithParameters), E_NOINTERFACE);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(43)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DB_E_BADBINDINFO
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_43()
|
|
{
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
HROW hRow = DB_NULL_HROW;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Create the rowset
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateCommand()==S_OK);
|
|
|
|
//Create an invalid Accessor for use with GetOriginalData
|
|
//Must be done on the CommandObject, ParameterAccessors are not allowed
|
|
//to be created on the RowsetObject
|
|
TEST2C_(hr = GetAccessorAndBindings(RowsetA.pICommand(),DBACCESSOR_PARAMETERDATA,&hAccessor,
|
|
NULL,NULL,NULL,DBPART_ALL,ALL_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_INPUT), S_OK, DB_E_BADACCESSORFLAGS);
|
|
|
|
if(hr == S_OK)
|
|
{
|
|
//Now that we have the Accessor Created, now create the rowset
|
|
//Must be a command query, since the accessor was created on the command
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(SELECT_REVCOLLIST)==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
//Call GetOriginalData with an invalid accessor type
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,hAccessor,RowsetA.m_pData),DB_E_BADACCESSORTYPE) ;
|
|
TESTC(RowsetA.m_pData!=NULL);
|
|
}
|
|
else
|
|
{
|
|
//Make sure the provider doesn't support parameters (validated immediately)
|
|
TESTC_(QI(RowsetA.pICommand(), IID_ICommandWithParameters), E_NOINTERFACE);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(44)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DB_E_COLUMNUNAVAILABLE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_44()
|
|
{
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
HROW hRow = DB_NULL_HROW;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Create the rowset
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateCommand()==S_OK);
|
|
|
|
//Create an invalid Accessor for use with GetOriginalData
|
|
//Must be done on the CommandObject, ParameterAccessors are not allowed
|
|
//to be created on the RowsetObject
|
|
TEST2C_(hr = GetAccessorAndBindings(RowsetA.pICommand(),DBACCESSOR_PARAMETERDATA,&hAccessor,
|
|
NULL,NULL,NULL,DBPART_ALL,ALL_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_INPUT), S_OK, DB_E_BADACCESSORFLAGS);
|
|
|
|
if(hr == S_OK)
|
|
{
|
|
//Now that we have the Accessor Created, now create the rowset
|
|
//Must be a command query, since the accessor was created on the command
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(SELECT_REVCOLLIST)==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
//Call GetOriginalData with an invalid accessor type
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,hAccessor,RowsetA.m_pData),DB_E_BADACCESSORTYPE);
|
|
TESTC(RowsetA.m_pData!=NULL);
|
|
}
|
|
else
|
|
{
|
|
//Make sure the provider doesn't support parameters (validated immediately)
|
|
TESTC_(QI(RowsetA.pICommand(), IID_ICommandWithParameters), E_NOINTERFACE);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(45)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_45()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(46)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Call GetOriginalData 3 times
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetOriginalRows::Variation_46()
|
|
{
|
|
void* pOriginalData = NULL;
|
|
void* pModifiedData = NULL;
|
|
|
|
void* pFirstCall = NULL;
|
|
void* pSecondCall = NULL;
|
|
void* pThirdCall = NULL;
|
|
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
pFirstCall = PROVIDER_ALLOC(sizeof(void*)*RowsetA.m_cRowSize);
|
|
pSecondCall = PROVIDER_ALLOC(sizeof(void*)*RowsetA.m_cRowSize);
|
|
pThirdCall = PROVIDER_ALLOC(sizeof(void*)*RowsetA.m_cRowSize);
|
|
|
|
//Obtain the row handle(s);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
//Save the OriginalData
|
|
TESTC_(RowsetA.GetRowData(hRow, &pOriginalData),S_OK);
|
|
|
|
//Modify the row
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
|
|
//Save the modified data
|
|
TESTC_(RowsetA.GetRowData(hRow, &pModifiedData),S_OK);
|
|
|
|
//Call GetOriginalData the first time
|
|
TESTC_(RowsetA.GetOriginalData(hRow, &pFirstCall),S_OK);
|
|
|
|
//Compare data with modified data, should not match
|
|
TESTC(!RowsetA.CompareRowData(pModifiedData,pFirstCall));
|
|
|
|
//Compare data with original data, should match
|
|
TESTC(RowsetA.CompareRowData(pOriginalData,pFirstCall));
|
|
|
|
//Modify the row again
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData the Second time
|
|
TESTC_(RowsetA.GetOriginalData(hRow, &pSecondCall),S_OK);
|
|
|
|
//Modify the row again
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData the Third time
|
|
TESTC_(RowsetA.GetOriginalData(hRow, &pThirdCall),S_OK);
|
|
|
|
//All three GetOriginalData calls should match, no update was performed
|
|
TESTC(RowsetA.CompareRowData(pFirstCall, pSecondCall));
|
|
TESTC(RowsetA.CompareRowData(pSecondCall, pThirdCall));
|
|
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(pModifiedData);
|
|
PROVIDER_FREE(pOriginalData);
|
|
|
|
PROVIDER_FREE(pFirstCall);
|
|
PROVIDER_FREE(pSecondCall);
|
|
PROVIDER_FREE(pThirdCall);
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetOriginalRows::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CRowsetUpdate::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCGetPendingRows)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCGetPendingRows - IRowsetUpdate::GetPendingRows test case
|
|
//| Created: 03/29/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetPendingRows::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CRowsetUpdate::Init())
|
|
// }}
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
return TEST_FAIL;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Verify GetPendingRows alters row handles correctly
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_1()
|
|
{
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HROW rghRow[THREE_ROWS] = {NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows = 0;
|
|
HROW* rgPendingRows = NULL;
|
|
ULONG* rgRefCounts = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
ULONG ulRefCount = 0;
|
|
DBSTATUS dwRowStatus = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, &cRowsObtained, rghRow),S_OK);
|
|
|
|
//Make change(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
//Release row handles
|
|
//DB_S_ERRORSOCCURRED - PendingChanges
|
|
TESTC_(RowsetA.ReleaseRows(cRowsObtained, rghRow, &rgRefCounts, &rgRowStatus),S_OK);
|
|
TESTC(rgRowStatus[ROW_ONE] == DBROWSTATUS_S_PENDINGCHANGES);
|
|
|
|
//Verify now invalid row handles
|
|
TESTC_(RowsetA.ReleaseRows(ONE_ROW, rghRow, &ulRefCount, &dwRowStatus), rgRefCounts[ROW_ONE] == 0 ? DB_E_ERRORSOCCURRED : S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(ONE_ROW, rghRow, &ulRefCount, &dwRowStatus), ulRefCount == 0 ? DB_E_ERRORSOCCURRED : S_OK);
|
|
|
|
//Call GetPendingRows, and have row handles retuned
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,NULL),S_OK);
|
|
TESTC(cPendingRows==ONE_ROW);
|
|
TESTC(rgPendingRows[0]==rghRow[ROW_ONE]);
|
|
|
|
//verify row handles have been refcounted, should be valid
|
|
TESTC_(RowsetA.ReleaseRows(cPendingRows, rgPendingRows, &ulRefCount, &dwRowStatus),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(cPendingRows, rgPendingRows), ulRefCount == 0 ? DB_E_ERRORSOCCURRED : S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(cPendingRows, rgPendingRows);
|
|
PROVIDER_FREE(rgRefCounts);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
PROVIDER_FREE(rgPendingRows);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, _ALL, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HROW* rghRows = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
//Grab all the rows in the rowset, provider alloced array
|
|
hr = RowsetA()->GetNextRows(NULL, 0, LONG_MAX, &cRowsObtained, &rghRows);
|
|
TESTC(hr==DB_S_ENDOFROWSET || hr==DB_S_ROWLIMITEXCEEDED || hr==E_OUTOFMEMORY);
|
|
if(hr==E_OUTOFMEMORY)
|
|
{
|
|
TESTC(cRowsObtained == 0);
|
|
TESTC(rghRows == NULL);
|
|
goto CLEANUP;
|
|
}
|
|
if(hr==DB_S_ROWLIMITEXCEEDED)
|
|
{
|
|
TESTC(RowsetA.GetMaxOpenRows() != 0);
|
|
TESTC(cRowsObtained && cRowsObtained<LONG_MAX);
|
|
TESTC(rghRows!=NULL);
|
|
}
|
|
else
|
|
{
|
|
TESTC(cRowsObtained && cRowsObtained<LONG_MAX && cRowsObtained >= 3);
|
|
TESTC(rghRows!=NULL);
|
|
}
|
|
|
|
//Modify Row 1
|
|
TESTC_(RowsetA.ModifyRow(rghRows[ROW_ONE]),S_OK)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL),S_OK);
|
|
|
|
//Delete Row 2
|
|
TESTC_PROVIDER(cRowsObtained >=2);
|
|
if(!RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(rghRows[ROW_TWO]),S_OK)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL),S_OK);
|
|
|
|
//Insert Row3
|
|
TESTC_PROVIDER(cRowsObtained >=3);
|
|
if(!RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
TESTC_(RowsetA.InsertRow(&rghRows[ROW_THREE]),S_OK)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(cRowsObtained,rghRows);
|
|
PROVIDER_FREE(rghRows);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [invalid, _ALL, NULL, invalid, invalid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_3()
|
|
{
|
|
TBEGIN
|
|
HROW rghRow[THREE_ROWS] = {NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//NOTE: We pass Invalid pointers to prgPendingRows and prgPendingStauts on input, since the
|
|
//spec states prgPendingRows and prgPendingStatus are ignored if pcPendingRows is NULL on input.
|
|
|
|
//insert row 1;
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_ONE]),S_OK)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(INVALID(HCHAPTER),DBPENDINGSTATUS_ALL,NULL,INVALID(HROW**),INVALID(ULONG**)),S_OK);
|
|
|
|
//insert row 2;
|
|
if(!RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_TWO]),S_OK)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(INVALID(HCHAPTER),DBPENDINGSTATUS_ALL,NULL,INVALID(HROW**),INVALID(ULONG**)),S_OK);
|
|
|
|
//insert row 3;
|
|
if(!RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(INVALID(HCHAPTER),DBPENDINGSTATUS_ALL,NULL,INVALID(HROW**),INVALID(ULONG**)),S_OK);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(THREE_ROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, _ALL, valid, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_4()
|
|
{
|
|
TBEGIN
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
DBCOUNTITEM cPendingRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, TWO_ROWS, rghRow),S_OK);
|
|
|
|
//Make change(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,NULL,NULL),S_OK);
|
|
COMPC(cPendingRows,ONE_ROW);
|
|
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(2));
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,NULL,NULL),S_OK);
|
|
COMPC(cPendingRows,TWO_ROWS);
|
|
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(3));
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK) //Insert row 3
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,NULL,NULL),S_OK);
|
|
COMPC(cPendingRows,THREE_ROWS);
|
|
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(4));
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_FOUR]),S_OK) //modify row 4
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK) //delete row 4
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,NULL,NULL),S_OK);
|
|
COMPC(cPendingRows,THREE_ROWS);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, _ALL, valid, NULL, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_5()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = SEVEN_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
|
|
DBCOUNTITEM cPendingRows = 0;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,THREE_ROWS,rghRow),S_OK);
|
|
|
|
//Make change(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
cModifiedRows++;
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
cModifiedRows++;
|
|
}
|
|
else
|
|
{
|
|
//Otherwise make sure the Data is unchanged...
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),DB_E_MAXPENDCHANGESEXCEEDED);
|
|
TESTC(RowsetA.CompareOrgRowData(rghRow[ROW_THREE]));
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //modify row 4;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK) //delete row 4;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(4))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_SIX]),S_OK) //insert row 6;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_SIX]),S_OK) //modify row 6;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_SIX]),S_OK) //delete row 6;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(5))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_SEVEN]),S_OK) //insert row 7;
|
|
cModifiedRows++;
|
|
}
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,NULL,&rgPendingStatus),S_OK);
|
|
COMPC(cPendingRows, cModifiedRows)
|
|
COMPC(rgPendingStatus[0], DBPENDINGSTATUS_CHANGED)
|
|
if(cModifiedRows >= 2)
|
|
COMPC(rgPendingStatus[1], DBPENDINGSTATUS_CHANGED)
|
|
if(cModifiedRows >= 3)
|
|
COMPC(rgPendingStatus[2], DBPENDINGSTATUS_NEW)
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgPendingStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, _ALL, valid, valid, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_6()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
DBCOUNTITEM cPendingRows = 0;
|
|
HROW* rgPendingRows = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Make change(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1
|
|
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(2));
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2
|
|
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(3));
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK) //insert row 3
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK) //delete row 3
|
|
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(4));
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_FOUR]),S_OK) //modify row 4
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK) //delete row 4
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,NULL),S_OK);
|
|
RowsetA.ReleaseRows(cPendingRows,rgPendingRows); //GetPendingRows refcounts
|
|
|
|
COMPC(cPendingRows,THREE_ROWS)
|
|
TESTC(rgPendingRows!=NULL);
|
|
COMPC(rgPendingRows[0],rghRow[ROW_ONE])
|
|
COMPC(rgPendingRows[1],rghRow[ROW_TWO])
|
|
COMPC(rgPendingRows[2],rghRow[ROW_FOUR])
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgPendingRows);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, _ALL, NULL, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_7()
|
|
{
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL),S_FALSE);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, _ALL, valid, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_8()
|
|
{
|
|
DBCOUNTITEM cPendingRows = 1;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,NULL,NULL),S_FALSE);
|
|
COMP(cPendingRows,NO_ROWS);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, _ALL, valid, valid, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_9()
|
|
{
|
|
DBCOUNTITEM cPendingRows = 1;
|
|
HROW* rgPendingRows = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,NULL),S_FALSE);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL) ;
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgPendingRows);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, _ALL, valid, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_10()
|
|
{
|
|
DBCOUNTITEM cPendingRows = 1;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_FALSE);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes (NULL, _ALL, valid, NULL, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_11()
|
|
{
|
|
DBCOUNTITEM cPendingRows = 1;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,NULL,&rgPendingStatus),S_FALSE);
|
|
TESTC(cPendingRows==NO_ROWS && rgPendingStatus==NULL);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Empty Rowset [NULL, _ALL, valid, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_12()
|
|
{
|
|
DBCOUNTITEM cPendingRows = 1;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate EmptyRowset;
|
|
TESTC_PROVIDER(EmptyRowset.CreateRowset(SELECT_EMPTYROWSET)==S_OK);
|
|
|
|
TESTC_(EmptyRowset.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_FALSE);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_13()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DBPENDINGSTATUS seperately, before any changes
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_14()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
ULONG cModifiedRows = 0;
|
|
ULONG cDeletedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//BEFORE CHANGES
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_NEW
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_NEW, NO_ROWS),S_FALSE);
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_CHANGED
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_CHANGED, NO_ROWS),S_FALSE);
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_DELETED
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED, NO_ROWS),S_FALSE);
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_ALL
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_ALL, NO_ROWS),S_FALSE);
|
|
|
|
//AFTER CHANGES
|
|
|
|
//Insert a row
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK) //Insert row;
|
|
|
|
//Modify a row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
cModifiedRows++;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Delete a row
|
|
if(RowsetA.AllowPendingRows(4))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK) //delete row 4;
|
|
cDeletedRows++;
|
|
}
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_NEW
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_NEW, ONE_ROW, DBPENDINGSTATUS_NEW),S_OK);
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_CHANGED
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_CHANGED, cModifiedRows, DBPENDINGSTATUS_CHANGED),cModifiedRows ? S_OK : S_FALSE);
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_DELETED
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED, cDeletedRows, DBPENDINGSTATUS_DELETED), cDeletedRows ? S_OK : S_FALSE);
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_ALL
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_ALL, 1 + cModifiedRows + cDeletedRows), S_OK);
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_UNCHANGED
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_UNCHANGED,NULL,NULL,NULL),E_INVALIDARG);
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_INVALIDROW
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_INVALIDROW,NULL,NULL,NULL),E_INVALIDARG);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DBPENDINGSTATUS_INVALIDROW
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_15()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_INVALIDROW
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_INVALIDROW,&cPendingRows,&rgPendingRows,&rgPendingStatus),E_INVALIDARG);
|
|
COMPC(cPendingRows, NO_ROWS);
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DBPENDINGSTATUS _NEW | _CHANGED | _SOFTDELETED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_16()
|
|
{
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK) //modify row 2;
|
|
|
|
//GetPendingRows NEW | CHANGED | SOFTDELETED
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_NEW |DBPENDINGSTATUS_CHANGED |DBPENDINGSTATUS_DELETED,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_OK);
|
|
RowsetA.ReleaseRows(cPendingRows,rgPendingRows); //GetPendingRows refcounts
|
|
|
|
COMPC(cPendingRows,ONE_ROW)
|
|
COMPC(rgPendingRows[0],rghRow[ROW_TWO])
|
|
COMPC(rgPendingStatus[0],DBPENDINGSTATUS_CHANGED)
|
|
|
|
PROVIDER_FREE(rgPendingRows);
|
|
PROVIDER_FREE(rgPendingStatus);
|
|
|
|
//GetPendingRows NEW | CHANGED | SOFTDELETED | UNCHANGED
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_NEW |DBPENDINGSTATUS_CHANGED |DBPENDINGSTATUS_DELETED|DBPENDINGSTATUS_UNCHANGED,&cPendingRows,&rgPendingRows,&rgPendingStatus),E_INVALIDARG);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgPendingRows);
|
|
PROVIDER_FREE(rgPendingStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DBPENDINGSTATUS_NEW, w/ no new rows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_17()
|
|
{
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Delete row(s)
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //modify row 2;
|
|
|
|
//GetPendingRows NEW, with no new rows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_NEW,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_FALSE);
|
|
COMPC(cPendingRows, NO_ROWS) //No NEW rows
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DBPENDINGSTATUS_CHANGED, w/ no changed rows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_18()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Insert row(s)
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK) //insert row;
|
|
|
|
//GetPendingRows CHANGED, with no modified rows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_CHANGED,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_FALSE);
|
|
COMPC(cPendingRows,NO_ROWS) //No changed rows
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DBPENDINGSTATUS_UNCHANGED, w/ all changed rows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_19()
|
|
{
|
|
const int NROWS = SEVEN_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Modify row(s)
|
|
cModifiedRows = RowsetA.GetMaxPendingRows();
|
|
if(cModifiedRows==0 || cModifiedRows > NROWS)
|
|
cModifiedRows = NROWS;
|
|
TESTC_(RowsetA.ModifyRow(cModifiedRows, rghRow),S_OK) //modify all rows;
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_UNCHANGED
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_UNCHANGED,&cPendingRows,&rgPendingRows,&rgPendingStatus),E_INVALIDARG);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - DBPENDINGSTATUS_DELETED, w/ no soft-deleted rows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_20()
|
|
{
|
|
HROW hNewRow = NULL;
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Insert row(s)
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(hNewRow),S_OK);
|
|
|
|
//GetPendingRows SOFTDELETED, with no deleted rows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_DELETED,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_FALSE);
|
|
COMPC(cPendingRows,NO_ROWS) //No soft-Deleted rows
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
//According to the 2.0 spec, InsertRow - SetData counts as NEW row not CHANGED
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_NEW, ONE_ROW),S_OK);
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_CHANGED, NO_ROWS),S_FALSE);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_21()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - _NEW | _UNCHANGED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_22()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Insert row(s)
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
|
|
//GetPendingRows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_UNCHANGED,&cPendingRows,&rgPendingRows,&rgPendingStatus),E_INVALIDARG);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - _NEW | _SOFTDELETED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_23()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Insert row(s)
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
//Modify row(s)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK);
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK);
|
|
|
|
//GetPendingRows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_DELETED,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_OK);
|
|
RowsetA.ReleaseRows(cPendingRows,rgPendingRows); //GetPendingRows refcounts
|
|
|
|
TESTC(cPendingRows == ONE_ROW);
|
|
TESTC(rgPendingRows!=NULL && rgPendingStatus!=NULL);
|
|
TESTC(rgPendingRows[0]==hNewRow);
|
|
TESTC(rgPendingStatus[0]==DBPENDINGSTATUS_NEW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_24()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Insert/Modify/Delete a single row
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_25()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Insert row(s)
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
//Delete row(s)
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//GetPendingRows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_FALSE);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_26()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Call GetPendingRows 3 times
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_27()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
ULONG cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Insert row(s)
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
cModifiedRows++;
|
|
|
|
//Modify row(s)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//GetPendingRows #1
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_ALL, cModifiedRows),S_OK);
|
|
|
|
//GetPendingRows #2
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_ALL, cModifiedRows),S_OK);
|
|
|
|
//Update
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//GetPendingRows #3
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_ALL, NO_ROWS),S_FALSE);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Modify the same row twice
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_28()
|
|
{
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, TWO_ROWS, rghRow),S_OK);
|
|
//Make a duplicate HROW, HROW3 == HROW1
|
|
rghRow[ROW_THREE] = rghRow[ROW_ONE];
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 1, duplicate;
|
|
|
|
//GetPendingRows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_OK);
|
|
RowsetA.ReleaseRows(cPendingRows,rgPendingRows); //GetPendingRows refcounts
|
|
|
|
COMPC(cPendingRows,ONE_ROW)
|
|
COMPC(rgPendingRows[0],rghRow[ROW_ONE])
|
|
COMPC(rgPendingStatus[0],DBPENDINGSTATUS_CHANGED)
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(TWO_ROWS,rghRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Modify the same row twice, undo, GetPendingRows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetPendingRows::Variation_29()
|
|
{
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, TWO_ROWS, rghRow),S_OK);
|
|
//Make a duplicate HROW, HROW3 == HROW1
|
|
rghRow[ROW_THREE] = rghRow[ROW_ONE];
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK) //delete row 1, duplicate;
|
|
|
|
//GetPendingRows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_OK);
|
|
RowsetA.ReleaseRows(cPendingRows,rgPendingRows); //GetPendingRows refcounts
|
|
|
|
COMPC(cPendingRows,ONE_ROW)
|
|
COMPC(rgPendingRows[0],rghRow[ROW_ONE])
|
|
COMPC(rgPendingStatus[0],DBPENDINGSTATUS_DELETED)
|
|
|
|
PROVIDER_FREE(rgPendingRows);
|
|
PROVIDER_FREE(rgPendingStatus);
|
|
|
|
//Undo all
|
|
TESTC_(RowsetA.UndoAll(),S_OK);
|
|
|
|
//GetPendingRows
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_FALSE);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(TWO_ROWS,rghRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetPendingRows::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CRowsetUpdate::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCUndo)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCUndo - IRowsetUpdate::Undo test case
|
|
//| Created: 03/29/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCUndo::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CRowsetUpdate::Init())
|
|
// }}
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
return TEST_FAIL;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, 0, NULL, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_1()
|
|
{
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,0,NULL,NULL,NULL,NULL),S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, N, valid, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_2()
|
|
{
|
|
HROW hInvalidRow = INVALID(HROW);
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,0,&hInvalidRow,NULL,NULL,NULL),S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL,0,NULL, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_3()
|
|
{
|
|
DBCOUNTITEM cRowsUndone = 1; //should be 0 on error
|
|
HROW* rgRowsUndone; //should be NULL on error
|
|
DBROWSTATUS* rgRowStatus;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,0,NULL,&cRowsUndone,&rgRowsUndone,&rgRowStatus),S_OK);
|
|
COMPC(cRowsUndone,NO_ROWS)
|
|
TESTC(rgRowsUndone==NULL && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [invalid, 1, NULL, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_4()
|
|
{
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
HROW* rgRowsUndone;
|
|
DBROWSTATUS* rgRowStatus;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(INVALID(HCHAPTER),ONE_ROW,NULL,&cRowsUndone,&rgRowsUndone,&rgRowStatus),E_INVALIDARG);
|
|
COMPC(cRowsUndone,NO_ROWS)
|
|
TESTC(rgRowsUndone==NULL && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, 0, NULL, NULL, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_5()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = SEVEN_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
|
|
HROW* rgRowsUndone = INVALID(HROW*);
|
|
DBROWSTATUS* rgRowStatus = INVALID(DBROWSTATUS*);
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_FOUR]),S_OK);
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_FIVE]),S_OK);
|
|
|
|
//Make change(s)
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK) //insert row 3;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
|
|
//Undo (0,NULL)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,0,NULL,NULL,&rgRowsUndone,&rgRowStatus),S_OK);
|
|
|
|
//Since pcRowsUndone==NULL, there can be no out arrays
|
|
//Should just ingore rgRowsUndone / rgRowStatus
|
|
TESTC(rgRowsUndone==INVALID(HROW*) && rgRowStatus==INVALID(DBROWSTATUS*));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, 0, valid, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_6()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK) ;
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_TWO]),S_OK) ;
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_FOUR]),S_OK) ;
|
|
|
|
//Make 2 changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2;
|
|
}
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK) //insert row 3;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK) //delete row 3;
|
|
}
|
|
|
|
//Call Undo, (all)
|
|
TESTC_(RowsetA.UndoRow(0,rghRow),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, N, valid, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_7()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
void* pOriginalData[NROWS] = {NULL,NULL,NULL};
|
|
void* pModifiedData[NROWS] = {NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK) ;
|
|
TESTC_(RowsetA.GetNextRows(SECOND_ROW,&rghRow[ROW_TWO]),S_OK);
|
|
rghRow[ROW_THREE] = rghRow[ROW_TWO]; //2 instances of the same hrow with changes
|
|
|
|
//Save Orginal Data
|
|
TESTC_(RowsetA.GetRowData(NROWS, rghRow, pOriginalData),S_OK);
|
|
|
|
//Make 2 changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK) //modify row 2;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK) //delete row 3;
|
|
|
|
//Save Modified Data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_ONE],&pModifiedData[0]),S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,NROWS,rghRow,NULL,NULL,&rgRowStatus),S_OK);
|
|
//rgRowStatus should be filled in
|
|
TESTC(rgRowStatus!=NULL);
|
|
TESTC(VerifyArray(NROWS,rgRowStatus,DBROWSTATUS_S_OK));
|
|
|
|
//Verify undo matched orginal data
|
|
TESTC(RowsetA.CompareRowData(NROWS, rghRow,pOriginalData));
|
|
//Verify undo does not match modified data
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_ONE],pModifiedData[0]));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE2(NROWS, pOriginalData);
|
|
PROVIDER_FREE2(NROWS, pModifiedData);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, N, valid, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_8()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK) ;
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_TWO]),S_OK) ;
|
|
rghRow[ROW_FOUR] = rghRow[ROW_TWO]; //2 instances of the same hrow with changes
|
|
|
|
//Make changes
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK) //insert row 3;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK) //delete row 3;
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2;
|
|
|
|
//Undo NROWS
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus!=NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[3]==DBROWSTATUS_S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [invalid, N, NULL, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cRowsUndone = 1; //should be 0 on error
|
|
HROW* rgRowsUndone; //should be NULL on error
|
|
DBROWSTATUS* rgRowStatus; //should be NULL on error
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK);
|
|
|
|
//Make 2 changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(INVALID(HCHAPTER),NROWS,NULL,&cRowsUndone,&rgRowsUndone,&rgRowStatus),E_INVALIDARG);
|
|
COMPC(cRowsUndone,NO_ROWS)
|
|
TESTC(rgRowsUndone==NULL && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [invalid, N, valid, valid, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_10()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
DBROWSTATUS* rgRowStatus = INVALID(DBROWSTATUS*);
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK) ;
|
|
|
|
//Make 2 changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,0,NULL,&cRowsUndone,NULL,&rgRowStatus),E_INVALIDARG);
|
|
COMPC(cRowsUndone,NO_ROWS);
|
|
TESTC(rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_11()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 invalid / 2 modified
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_12()
|
|
{
|
|
void* pOriginalData = NULL;
|
|
void* pModifiedData = NULL;
|
|
|
|
const int NROWS = FIVE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
|
|
rghRow[ROW_ONE] = DB_NULL_HROW; //invalid
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,TWO_ROWS,&rghRow[ROW_TWO]),S_OK) ;
|
|
rghRow[ROW_FOUR] = INVALID(HROW); //invalid
|
|
rghRow[ROW_FIVE] = DB_NULL_HROW; //invalid
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_THREE], &pOriginalData),S_OK);
|
|
|
|
//Delete/Modify the row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
|
|
//Save the modified row data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_THREE], &pModifiedData),S_OK);
|
|
|
|
//Call Undo on the modified/invlaid row(s)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus!=NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_E_INVALID);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[3]==DBROWSTATUS_E_INVALID);
|
|
TESTC(rgRowStatus[4]==DBROWSTATUS_E_INVALID);
|
|
|
|
//Compare data with orginal data, should be equal, undo was called
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_THREE], pOriginalData));
|
|
|
|
//Compare data with modified data, should not be equal, undo was called
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_THREE], pModifiedData));
|
|
|
|
CLEANUP:
|
|
//Release the row handles
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pModifiedData);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 1 hard del / 1 invalid / 1 modified
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_13()
|
|
{
|
|
TBEGIN
|
|
void* pOriginalData = NULL;
|
|
void* pModifiedData = NULL;
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
rghRow[ROW_ONE] = DB_NULL_HROW;
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_TWO]),S_OK) ;
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_THREE]),S_OK);
|
|
|
|
//Save the orginal modified row data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_TWO], &pOriginalData),S_OK);
|
|
|
|
//Hard delete the row
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_THREE]),S_OK) //hard-delete row 3;
|
|
|
|
//Modify/delete row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK) //modify row 2;
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_TWO], &pModifiedData),S_OK);
|
|
|
|
//Call Undo on the modified/invlaid row(s)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus!=NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_E_INVALID);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_E_DELETED);
|
|
|
|
//Compare data with orginal data, should be equal, undo was called
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_TWO],pOriginalData));
|
|
|
|
//Compare data with modified data, should not be equal, undo was called
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_TWO],pModifiedData));
|
|
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pModifiedData);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 1 hard del / 1 invalid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_14()
|
|
{
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
rghRow[ROW_ONE] = DB_NULL_HROW;
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_TWO]),S_OK) ;
|
|
rghRow[ROW_THREE] = rghRow[ROW_TWO]; //row 3 == row 2 duplicate
|
|
|
|
//Hard-Delete row(s)
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_TWO]),S_OK) //hard-delete row 2;
|
|
|
|
//Call Undo on the modified/invlaid row(s)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_E_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus!=NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_E_INVALID);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_E_DELETED);
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 soft del / 2 orginal
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_15()
|
|
{
|
|
const int NROWS = FIVE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
void* pOriginalData[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK) ;
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(NROWS, rghRow, pOriginalData),S_OK);
|
|
|
|
//Delete the row(s)
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_ONE]),S_OK) //delete row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK) //delete row 3;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FIVE]),S_OK) //delete row 5;
|
|
|
|
//Call Undo on the deleted/orginal row(s)
|
|
TESTC_(RowsetA.UndoRow(NROWS,rghRow),S_OK);
|
|
|
|
//Compare data with orginal data, should be equal, undo was called
|
|
TESTC(RowsetA.CompareRowData(NROWS, rghRow, pOriginalData));
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE2(NROWS, pOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 new rows / 1 orginal
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_16()
|
|
{
|
|
TBEGIN
|
|
void* pOriginalData = NULL;
|
|
void* pData = NULL;
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
pData = PROVIDER_ALLOC(sizeof(void*)*RowsetA.m_cRowSize);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
TESTC_(RowsetA.GetRow(SECOND_ROW, &rghRow[ROW_THREE]),S_OK) //get row 3;
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_ONE]),S_OK) //insert row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_TWO]),S_OK) //insert row 2;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4;
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_THREE], &pOriginalData),S_OK) //orginal;
|
|
|
|
//Call Undo on the inserted/orginal row(s)
|
|
TESTC_(RowsetA.UndoRow(NROWS,rghRow),RowsetA.AllowPendingRows(3) ? S_OK : DB_S_ERRORSOCCURRED);
|
|
|
|
//Compare data with orginal data, should be equal, undo was called
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_THREE], pOriginalData));
|
|
|
|
//Inserted rows should no longer exists...
|
|
//TESTC(!ValidRow(rghRow[ROW_ONE]));
|
|
//TESTC(!ValidRow(rghRow[ROW_TWO]));
|
|
//TESTC(!ValidRow(rghRow[ROW_FOUR]));
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 4 modified / 3 orginal
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_17()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
void* pOriginalData[NROWS] = {NULL,NULL,NULL,NULL};
|
|
void* pModifiedData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK) ;
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(NROWS, rghRow, pOriginalData),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
|
|
//Save the modified row data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_THREE], &pModifiedData),S_OK);
|
|
|
|
//Call Undo on the deleted/orginal row(s)
|
|
TESTC_(RowsetA.UndoRow(NROWS,rghRow),S_OK);
|
|
|
|
//Compare data with orginal data, should be equal, undo was called
|
|
TESTC(RowsetA.CompareRowData(NROWS, rghRow, pOriginalData));
|
|
|
|
//Compare data with modified data, should not be equal, undo was called
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_THREE], pModifiedData));
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE2(NROWS, pOriginalData);
|
|
PROVIDER_FREE(pModifiedData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 soft del / 2 orginal, update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_18()
|
|
{
|
|
const int NROWS = FIVE_ROWS;
|
|
|
|
void* pOriginalData[NROWS] = {NULL,NULL,NULL,NULL};
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
ULONG cDeletedRows = 0;
|
|
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK) ;
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(NROWS, rghRow, pOriginalData),S_OK);
|
|
|
|
//Delete the row(s)
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_ONE]),S_OK) //delete row 1;
|
|
cDeletedRows++;
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK) //delete row 3;
|
|
cDeletedRows++;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FIVE]),S_OK) //delete row 5;
|
|
cDeletedRows++;
|
|
}
|
|
|
|
//Update
|
|
TESTC_(RowsetA.UpdateRow(NROWS,rghRow),S_OK);
|
|
|
|
//Call Undo on the deleted/orginal row(s)
|
|
//I could just Undo all, but since I want to pound on the array that is
|
|
//holding the pending rows, try undoing every other row in the array
|
|
|
|
//deleted
|
|
TESTC_(RowsetA.UndoRow(NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
COMPC(rgRowStatus[0], DBROWSTATUS_E_DELETED);
|
|
COMPC(rgRowStatus[1], DBROWSTATUS_S_OK);
|
|
COMPC(rgRowStatus[2], (DBROWSTATUS)((cDeletedRows >= 2) ? DBROWSTATUS_E_DELETED : DBROWSTATUS_S_OK));
|
|
COMPC(rgRowStatus[3], DBROWSTATUS_S_OK);
|
|
COMPC(rgRowStatus[4], (DBROWSTATUS)((cDeletedRows >= 3) ? DBROWSTATUS_E_DELETED : DBROWSTATUS_S_OK));
|
|
|
|
//Compare orginal rows with orginal data, should be equal, no change
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_TWO], pOriginalData[1]));
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_FOUR], pOriginalData[3]));
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE2(NROWS, pOriginalData);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(THREE_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 new rows / 1 orginal, update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_19()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
ULONG cRows = 0;
|
|
|
|
void* pOriginalData[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
TESTC_(RowsetA.GetRow(SECOND_ROW, &rghRow[ROW_ONE]),S_OK);
|
|
cRows++;
|
|
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_TWO]),S_OK);
|
|
cRows++;
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK);
|
|
cRows++;
|
|
}
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK);
|
|
cRows++;
|
|
}
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(cRows, rghRow, pOriginalData),S_OK);
|
|
|
|
//Update all row(s)
|
|
TESTC_(RowsetA.UpdateRow(cRows, rghRow),S_OK);
|
|
|
|
//Call Undo on the inserted/orginal row(s)
|
|
TESTC_(RowsetA.UndoRow(cRows, rghRow),S_OK);
|
|
|
|
//Compare data with orginal data, should be equal, undo was called
|
|
//Inserted rows should exists, since update was called
|
|
TESTC(RowsetA.CompareRowData(cRows, rghRow, pOriginalData));
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE2(NROWS, pOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 4 modified / 3 orginal, update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_20()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
void* pOriginalData[NROWS] = {NULL,NULL,NULL,NULL};
|
|
void* pModifiedData = NULL;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK) ;
|
|
|
|
//Save the orginal row(s) data
|
|
TESTC_(RowsetA.GetRowData(NROWS, rghRow, pOriginalData),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
|
|
//Save the modified row data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_THREE], &pModifiedData),S_OK);
|
|
|
|
//Update
|
|
TESTC_(RowsetA.UpdateRow(NROWS,rghRow),S_OK);
|
|
|
|
//Call Undo
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone),S_OK);
|
|
TESTC(cRowsUndone==NO_ROWS);
|
|
|
|
//Compare with orginal data, should not be equal, update was called
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_THREE], pOriginalData[2]));
|
|
|
|
//Compare with modified data, should be equal, update was called
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_THREE], pModifiedData));
|
|
|
|
//Compare orginal rows, should be equal to prginal data, no change
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_ONE], pOriginalData[0]));
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_TWO], pOriginalData[1]));
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_FOUR], pOriginalData[3]));
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE2(NROWS,pOriginalData);
|
|
PROVIDER_FREE(pModifiedData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 hard del / 2 modified
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_21()
|
|
{
|
|
void* pOriginalData = NULL;
|
|
void* pModifiedData = NULL;
|
|
|
|
const int NROWS = FIVE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1, get 5 handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK);
|
|
|
|
//Save the orginal row data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_TWO], &pOriginalData),S_OK);
|
|
|
|
//Hard-Delete the row(s)
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_THREE]),S_OK);
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_FIVE]),S_OK);
|
|
|
|
//Modify the row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK) //modified;
|
|
|
|
//Save the modified row data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_TWO], &pModifiedData),S_OK);
|
|
|
|
//Call Undo on the modified/deleted row(s)
|
|
//I could just Undo all, but since I want to pound on the array that is
|
|
//holding the pending rows, try undoing every other row in the array
|
|
|
|
//deleted
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
|
|
//Verify output
|
|
TESTC(rgRowStatus!=NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[3]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[4]==DBROWSTATUS_E_DELETED);
|
|
|
|
//Compare data with orginal data, should be equal, undo was called
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_TWO],pOriginalData));
|
|
|
|
//Compare data with modified data, should not be equal, undo was called
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_TWO],pModifiedData));
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pModifiedData);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(THREE_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Insert/Modify/Delete a single row
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_22()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Insert row
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
//Modify row
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
//Delete row
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//Call Undo
|
|
//An inserted row has been deleted. This row is now an invalid state, and is no
|
|
//no longer pending (see GetPendingRows), and IRowsetUpdate::Undo with (0,NULL)
|
|
//only undoes pending rows, thus there are no pending rows to undo, thus S_OK...
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone),S_OK);
|
|
TESTC(cRowsUndone==NO_ROWS);
|
|
|
|
//Row should no longer exists
|
|
TESTC_(RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),DB_E_DELETEDROW);
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Insert/Modify/Delete a single row, Update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_23()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Insert row
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
//Modify row
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
//Delete row
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//Update
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//Call Undo
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone),S_OK);
|
|
TESTC(cRowsUndone==NO_ROWS);
|
|
|
|
//Row should not exists, update was called
|
|
TESTC_(RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),DB_E_DELETEDROW);
|
|
|
|
CLEANUP:
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Duplicate entries in the array
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_24()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
ULONG cRowsUndone = 1;
|
|
HROW* rgRowsUndone = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, TWO_ROWS, rghRow),S_OK);
|
|
|
|
//Make a duplicate HROW,
|
|
rghRow[ROW_THREE] = rghRow[ROW_ONE]; // HROW3 == HROW1
|
|
rghRow[ROW_FOUR] = rghRow[ROW_TWO]; // HROW4 == HROW2
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 1, duplicate;
|
|
|
|
//Call Undo
|
|
TESTC_(RowsetA.UndoRow(NROWS,rghRow),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
PROVIDER_FREE(rgRowsUndone);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_25()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Fetch every other row, modify every even, undo all odd.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_26()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = SIX_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Modify every even row
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK);
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_FOUR]),S_OK);
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_SIX]),S_OK);
|
|
|
|
//Now internally there should be an array of every other row
|
|
//Just to pound on that array, will insert delete a couple of rows from the middle
|
|
if(RowsetA.AllowPendingRows(4))
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
if(RowsetA.AllowPendingRows(5))
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_FOUR]),S_OK);
|
|
|
|
//Now Undo every even
|
|
TESTC_(RowsetA.UndoRow(rghRow[ROW_TWO]),S_OK);
|
|
TESTC_(RowsetA.UndoRow(rghRow[ROW_FOUR]), RowsetA.AllowPendingRows(5) ? DB_E_ERRORSOCCURRED : S_OK);
|
|
TESTC_(RowsetA.UndoRow(rghRow[ROW_SIX]),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Call Undo 3 times
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_27()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = SIX_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
DBCOUNTITEM cRowsUndone = 0;
|
|
HROW* rgRowsUndone = NULL;
|
|
DBROWSTATUS* rgRowStatus = PROVIDER_ALLOC_(1,DBROWSTATUS);
|
|
ULONG ulRefCount = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Insert row(s)
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK) //insert row 7;
|
|
cModifiedRows++;
|
|
|
|
//Release some of the Rows, just to make sure that the changes
|
|
//are not lost, and that internally the provider doesn't have a problem
|
|
//trying to undo pending changes where the row refount is released...
|
|
TESTC_(RowsetA.ReleaseRows(1, &hNewRow, &ulRefCount),S_OK);
|
|
RowsetA.ReleaseRows(1, &hNewRow, &ulRefCount);
|
|
|
|
//Modify row(s)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
cModifiedRows++;
|
|
}
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK) //modify row 2;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2;
|
|
cModifiedRows++;
|
|
}
|
|
if(RowsetA.AllowPendingRows(4))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_SIX]),S_OK) //modify row 6;
|
|
TESTC_(RowsetA.ReleaseRows(rghRow[ROW_SIX]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Call Undo #1
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone,&rgRowsUndone),S_OK);
|
|
TESTC(cRowsUndone==cModifiedRows && rgRowsUndone!=NULL);
|
|
|
|
//Since 0, NULL was passed the returned array is not required to be ordered
|
|
//In the same order of the changes.
|
|
TESTC(FindValue(hNewRow, cRowsUndone, rgRowsUndone));
|
|
if(cModifiedRows >= 2)
|
|
TESTC(FindValue(rghRow[ROW_ONE], cRowsUndone, rgRowsUndone));
|
|
if(cModifiedRows >= 3)
|
|
TESTC(FindValue(rghRow[ROW_TWO], cRowsUndone, rgRowsUndone));
|
|
if(cModifiedRows >= 4)
|
|
TESTC(FindValue(rghRow[ROW_SIX], cRowsUndone, rgRowsUndone));
|
|
|
|
//Call Undo #2
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone),S_OK);
|
|
TESTC(cRowsUndone==NO_ROWS);
|
|
|
|
//Delete row(s) (row was already released)
|
|
TESTC_(RowsetA.pIRowsetUpdate()->DeleteRows(NULL,ONE_ROW,&hNewRow,rgRowStatus),DB_E_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0] == (DBROWSTATUS)(ulRefCount ? DBROWSTATUS_E_DELETED : DBROWSTATUS_E_INVALID));
|
|
|
|
//Call Undo #3
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone),S_OK);
|
|
TESTC(cRowsUndone==NO_ROWS);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
PROVIDER_FREE(rgRowsUndone);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_28()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Empty Rowset [NULL, 0 ,NULL, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_29()
|
|
{
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
|
|
CRowsetUpdate EmptyRowset;
|
|
TESTC_PROVIDER(EmptyRowset.CreateRowset(SELECT_EMPTYROWSET)==S_OK);
|
|
|
|
TESTC_(EmptyRowset.UndoRow(0,NULL,&cRowsUndone),S_OK);
|
|
TESTC(cRowsUndone==NO_ROWS);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_30()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Accessor - BLOB / Long columns - SetPos
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_31()
|
|
{
|
|
TBEGIN
|
|
TRETURN //TODO need to work on blob support once supported
|
|
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
HROW hNewRow = DB_NULL_HROW;
|
|
DBLENGTH cRowSize = 0;
|
|
|
|
void* pInsertData = NULL;
|
|
void* pModifyData = NULL;
|
|
|
|
void* pData1 = NULL;
|
|
void* pData2 = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetLocate);
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Create Accessor binding BLOB/Long data (last param TRUE)
|
|
TESTC_(GetAccessorAndBindings(RowsetA(),DBACCESSOR_ROWDATA,&hAccessor,
|
|
NULL,NULL,&cRowSize,DBPART_ALL,UPDATEABLE_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_NOTPARAM, BLOB_LONG), S_OK);
|
|
|
|
//Alloc buffers
|
|
TESTC(RowsetA.MakeRowData(&pInsertData,hAccessor));
|
|
TESTC(RowsetA.MakeRowData(&pModifyData,hAccessor));
|
|
pData1 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
pData2 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
|
|
//Get Rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Get the Data
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData1),S_OK);
|
|
|
|
//Modify a row (BLOB data)
|
|
TESTC_(RowsetA.pIRowsetChange()->SetData(rghRow[ROW_ONE],hAccessor, pModifyData),S_OK);
|
|
//Insert a row (BLOB data)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.pIRowsetChange()->InsertRow(NULL,hAccessor, pInsertData, &hNewRow),S_OK);
|
|
//Delete a row (BLOB data)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Before undo, should be equal
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData2),S_OK);
|
|
TESTC(RowsetA.CompareRowData(pData2, pModifyData, hAccessor));
|
|
|
|
//Now call Undo
|
|
TESTC_(RowsetA.UndoAll(),S_OK);
|
|
|
|
//After undo, should not be equal
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData2),S_OK);
|
|
TESTC(!RowsetA.CompareRowData(pData2, pModifyData, hAccessor));
|
|
|
|
|
|
CLEANUP:
|
|
//Free Data
|
|
RowsetA.ReleaseRowData(pInsertData,hAccessor);
|
|
RowsetA.ReleaseRowData(pModifyData,hAccessor);
|
|
|
|
//Release the Accesssor
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
|
|
PROVIDER_FREE(pData1);
|
|
PROVIDER_FREE(pData2);
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Accessor - BLOB / Long columns - QBU
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_32()
|
|
{
|
|
TBEGIN
|
|
TRETURN //TODO need to work on blob support once supported
|
|
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
HROW hNewRow = DB_NULL_HROW;
|
|
DBLENGTH cRowSize = 0;
|
|
|
|
void* pInsertData = NULL;
|
|
void* pModifyData = NULL;
|
|
|
|
void* pData1 = NULL;
|
|
void* pData2 = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetLocate);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Create Accessor binding BLOB/Long data (last param TRUE)
|
|
TESTC_(GetAccessorAndBindings(RowsetA(),DBACCESSOR_ROWDATA,&hAccessor,
|
|
NULL,NULL,&cRowSize,DBPART_ALL,UPDATEABLE_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_NOTPARAM, BLOB_LONG), S_OK);
|
|
|
|
//Alloc buffers
|
|
TESTC(RowsetA.MakeRowData(&pInsertData,hAccessor));
|
|
TESTC(RowsetA.MakeRowData(&pModifyData,hAccessor));
|
|
pData1 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
pData2 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
|
|
//Get Rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Get the Data
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData1),S_OK);
|
|
|
|
//Modify a row (BLOB data)
|
|
TESTC_(RowsetA.pIRowsetChange()->SetData(rghRow[ROW_ONE],hAccessor, pModifyData),S_OK);
|
|
//Insert a row (BLOB data)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.pIRowsetChange()->InsertRow(NULL,hAccessor, pInsertData, &hNewRow),S_OK);
|
|
//Delete a row (BLOB data)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Before undo, should be equal
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData2),S_OK);
|
|
TESTC(RowsetA.CompareRowData(pData2, pModifyData, hAccessor));
|
|
|
|
//Now call Undo
|
|
TESTC_(RowsetA.UndoAll(),S_OK);
|
|
|
|
//After undo, should not be equal
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData2),S_OK);
|
|
TESTC(!RowsetA.CompareRowData(pData2, pModifyData, hAccessor));
|
|
|
|
|
|
CLEANUP:
|
|
//Free Data
|
|
RowsetA.ReleaseRowData(pInsertData,hAccessor);
|
|
RowsetA.ReleaseRowData(pModifyData,hAccessor);
|
|
|
|
//Release the Accesssor
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
|
|
PROVIDER_FREE(pData1);
|
|
PROVIDER_FREE(pData2);
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_33()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Soft-Deleted/Undo verify valid row handle
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_34()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
HROW* rgRowsUndone = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Delete row(s)
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK);
|
|
cModifiedRows++;
|
|
|
|
//Insert row(s)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Modify row(s)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Call Undo
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone,&rgRowsUndone),S_OK);
|
|
COMPC(cRowsUndone, cModifiedRows);
|
|
|
|
//Since 0, NULL was passed the returned array is not required to be ordered
|
|
//In the same order of the changes.
|
|
TESTC(FindValue(rghRow[ROW_THREE], cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_THREE], &RowsetA.m_pData),S_OK);
|
|
if(cModifiedRows >= 2)
|
|
{
|
|
TESTC(FindValue(hNewRow, cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(hNewRow, &RowsetA.m_pData),DB_E_DELETEDROW);
|
|
}
|
|
if(cModifiedRows >= 3)
|
|
{
|
|
TESTC(FindValue(rghRow[ROW_ONE], cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &RowsetA.m_pData),S_OK);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
PROVIDER_FREE(rgRowsUndone);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Inserted/Undo verify invalid row handle
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_35()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
HROW* rgRowsUndone = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Insert row(s)
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
cModifiedRows++;
|
|
|
|
//Modify row(s)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
//Delete row(s)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Call Undo
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone,&rgRowsUndone),S_OK);
|
|
COMPC(cRowsUndone, cModifiedRows)
|
|
|
|
//Since 0, NULL was passed the returned array is not required to be ordered
|
|
//In the same order of the changes.
|
|
TESTC(FindValue(hNewRow, cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(hNewRow, &RowsetA.m_pData),DB_E_DELETEDROW);
|
|
if(cModifiedRows >= 2)
|
|
{
|
|
TESTC(FindValue(rghRow[ROW_ONE], cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &RowsetA.m_pData),S_OK);
|
|
}
|
|
if(cModifiedRows >= 3)
|
|
{
|
|
TESTC(FindValue(rghRow[ROW_THREE], cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_THREE], &RowsetA.m_pData),S_OK);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
PROVIDER_FREE(rgRowsUndone);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Modified/Undo verify valid row handle, and OriginalData
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_36()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
HROW* rgRowsUndone = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
void* pOriginalData = NULL;
|
|
void* pModifiedData = NULL;
|
|
void* pData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
pData = PROVIDER_ALLOC(sizeof(void*)*RowsetA.m_cRowSize);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Save OriginalData
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_ONE],&pOriginalData),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
cModifiedRows++;
|
|
|
|
//Insert row(s)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Delete row(s)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Save ModifiedData
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_ONE],&pModifiedData),S_OK);
|
|
|
|
//Call Undo
|
|
TESTC_(RowsetA.UndoRow(0,NULL,&cRowsUndone,&rgRowsUndone),S_OK);
|
|
COMPC(cRowsUndone, cModifiedRows)
|
|
|
|
//Since 0, NULL was passed the returned array is not required to be ordered
|
|
//In the same order of the changes.
|
|
TESTC(FindValue(rghRow[ROW_ONE], cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &pData),S_OK);
|
|
|
|
if(cModifiedRows >= 2)
|
|
{
|
|
TESTC(FindValue(hNewRow, cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(hNewRow, &pData),DB_E_DELETEDROW);
|
|
}
|
|
if(cModifiedRows >= 3)
|
|
{
|
|
TESTC(FindValue(rghRow[ROW_THREE], cRowsUndone, rgRowsUndone));
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_THREE], &pData),S_OK);
|
|
}
|
|
|
|
//Verify modified/undo data
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_ONE],pOriginalData));
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_ONE],pModifiedData));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
|
|
PROVIDER_FREE(pData);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pModifiedData);
|
|
PROVIDER_FREE(rgRowsUndone);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Verify Undo alters row handle refcount correctly
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUndo::Variation_37()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
HROW hNewRow = NULL;
|
|
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
HROW* rgRowsUndone = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Delete row(s)
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK);
|
|
cModifiedRows++;
|
|
|
|
//Insert row(s)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Modify row(s)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Release all the rows
|
|
TESTC_(RowsetA.ReleaseRows(NROWS, rghRow, NULL, &rgRowStatus),S_OK) //Will return DBROWSTATUS_S_PENDINGCHANGES;
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[ROW_ONE] == (DBROWSTATUS)(cModifiedRows>=3 ? DBROWSTATUS_S_PENDINGCHANGES : DBROWSTATUS_S_OK));
|
|
TESTC(rgRowStatus[ROW_TWO] == DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[ROW_THREE] == DBROWSTATUS_S_PENDINGCHANGES);
|
|
|
|
if(hNewRow)
|
|
{
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TESTC_(RowsetA.ReleaseRows(ONE_ROW, &hNewRow, NULL, &rgRowStatus),S_OK) //Will return DBROWSTATUS_S_PENDINGCHANGES;
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0] == DBROWSTATUS_S_PENDINGCHANGES);
|
|
}
|
|
|
|
//Call Undo
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Undo(NULL,0,NULL,&cRowsUndone,&rgRowsUndone,&rgRowStatus),S_OK);
|
|
COMPC(cRowsUndone, cModifiedRows)
|
|
|
|
//Since 0, NULL was passed the returned array is not required to be ordered
|
|
//In the same order of the changes.
|
|
TESTC(FindValue(rghRow[ROW_THREE], cRowsUndone, rgRowsUndone));
|
|
VerifyArray(cRowsUndone, rgRowStatus, DBROWSTATUS_S_OK);
|
|
if(cModifiedRows >= 2)
|
|
TESTC(FindValue(hNewRow, cRowsUndone, rgRowsUndone));
|
|
if(cModifiedRows >= 3)
|
|
TESTC(FindValue(rghRow[ROW_ONE], cRowsUndone, rgRowsUndone));
|
|
|
|
//Release again, should be fine
|
|
TESTC_(RowsetA.ReleaseRows(cRowsUndone,rgRowsUndone),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
PROVIDER_FREE(rgRowsUndone);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCUndo::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CRowsetUpdate::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCUpdate)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCUpdate - IRowsetUpdate::Update test case
|
|
//| Created: 03/29/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCUpdate::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CRowsetUpdate::Init())
|
|
// }}
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
return TEST_FAIL;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, 0, NULL,NULL,NULL,NULL,NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_1()
|
|
{
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Update(NULL,0,NULL,NULL,NULL,NULL),S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes (NULL, 0, NULL, valid, valid, valid, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_2()
|
|
{
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(RowsetA.UpdateRow(0,NULL),S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes (NULL, N, valid, NULL, NULL, valid, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_3()
|
|
{
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK);
|
|
|
|
//Make changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_FOUR]),S_OK) //modify row 4;
|
|
if(RowsetA.AllowPendingRows(4))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK) //delete row 4;
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Update(NULL,NROWS,rghRow,NULL,NULL,&rgRowStatus),S_OK);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(VerifyArray(NROWS,rgRowStatus,DBROWSTATUS_S_OK));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(TWO_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes (invalid, N, NULL, valid, valid, valid, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_4()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS,rghRow),S_OK);
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Update(INVALID(HCHAPTER),NROWS,NULL,&cUpdatedRows,&rgUpdatedRows,&rgRowStatus),E_INVALIDARG);
|
|
TESTC(cUpdatedRows==0 && rgUpdatedRows==NULL && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes (invalid, N, valid, valid, NULL, valid, valid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_5()
|
|
{
|
|
TBEGIN
|
|
HROW* rgUpdatedRows = INVALID(HROW*);
|
|
DBROWSTATUS* rgRowStatus = INVALID(DBROWSTATUS*);
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS,rghRow),S_OK);
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK) //insert row 3;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK) //delete row 3;
|
|
}
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Update(NULL,0,NULL,NULL,&rgUpdatedRows,&rgRowStatus),S_OK);
|
|
//rgUpdatedRows / rgRowStatus should just be ignored since, pcUpdaedRows==NULL
|
|
TESTC(rgUpdatedRows==INVALID(HROW*) && rgRowStatus==INVALID(DBROWSTATUS*));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TableInsert(TWO_ROWS); //Adjust the table
|
|
TRETURN;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes (NULL, 0, NULL, valid, valid, valid, NULL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_6()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS,rghRow),S_OK);
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK) //insert row 3;
|
|
|
|
TESTC_(RowsetA.pIRowsetUpdate()->Update(NULL,0,NULL,&cUpdatedRows,NULL,&rgRowStatus),E_INVALIDARG);
|
|
TESTC(cUpdatedRows==0 && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes (NULL, 0, NULL, NULL, NULL, NULL, NULL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_7()
|
|
{
|
|
HROW hNewRow = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.InsertRow(&hNewRow),S_OK) //insert row;
|
|
|
|
TESTC_(RowsetA.UpdateRow(hNewRow),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes (NULL, 0, NULL, valid, valid,valid,valid,
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_8()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,TWO_ROWS,rghRow),S_OK);
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
cModifiedRows++;
|
|
|
|
//Release some of the rows, so we know that the provider doesn't have a
|
|
//problem trying to update pending rows, that have been released...
|
|
TESTC_(RowsetA.ReleaseRows(rghRow[ROW_ONE]),S_OK);
|
|
RowsetA.ReleaseRows(rghRow[ROW_ONE]);
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2;
|
|
TESTC_(RowsetA.ReleaseRows(rghRow[ROW_TWO]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK) //delete row 4;
|
|
}
|
|
|
|
//Update (0,NULL)
|
|
TESTC_(RowsetA.UpdateRow(0,NULL,&cUpdatedRows,&rgUpdatedRows),S_OK);
|
|
TESTC(cUpdatedRows==cModifiedRows);
|
|
COMPC(rgUpdatedRows[0],rghRow[ROW_ONE])
|
|
if(cModifiedRows >= 2)
|
|
COMPC(rgUpdatedRows[1],rghRow[ROW_TWO])
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS,rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
TableInsert(TWO_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Empty Rowset (NULL, 0, NULL, valid, valid,valid,valid,
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_9()
|
|
{
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
HROW* rgRowsUndone = NULL;
|
|
|
|
CRowsetUpdate EmptyRowset;
|
|
TESTC_PROVIDER(EmptyRowset.CreateRowset(SELECT_EMPTYROWSET)==S_OK);
|
|
|
|
TESTC_(EmptyRowset.UpdateRow(0,NULL,&cRowsUndone,&rgRowsUndone),S_OK);
|
|
TESTC(cRowsUndone==0 && rgRowsUndone==NULL);
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgRowsUndone)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_10()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 hard deleted / 2 modified
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_11()
|
|
{
|
|
const int NROWS = FIVE_ROWS;
|
|
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
void* pOriginalData = NULL;
|
|
void* pModifiedData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK) ;
|
|
|
|
//Save orginal data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_ONE],&pOriginalData),S_OK) //save row 1 old data;
|
|
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2;
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_FOUR]),S_OK)//delete row 4;
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_FIVE]),S_OK)//delete row 5;
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
|
|
//Save modified data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_ONE], &pModifiedData),S_OK) //save row 1 new data;
|
|
|
|
TESTC_(RowsetA.UpdateRow(NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[3]==DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[4]==DBROWSTATUS_E_DELETED);
|
|
|
|
//Verify Update did update the data at the backend
|
|
// TESTC(RowsetA.CompareTableData(FIRST_ROW, rghRow[ROW_ONE]));
|
|
// TESTC(RowsetA.CompareTableData(THIRD_ROW, rghRow[ROW_THREE]));
|
|
|
|
//Verify Update did update the data in the rowset
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_ONE],pModifiedData));
|
|
|
|
//Verify Updated data does not equal orginal data
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_ONE],pOriginalData));
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
|
|
PROVIDER_FREE(rgRowStatus);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pModifiedData);
|
|
TableInsert(THREE_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 invalid / 2 inserted
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_12()
|
|
{
|
|
const int NROWS = FIVE_ROWS;
|
|
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
void* pOriginalData = NULL;
|
|
void* pModifiedData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK) ;
|
|
|
|
//Save orginal data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_THREE],&pOriginalData),S_OK) //save row 3 old data;
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_FIVE]),S_OK)//delete row 5;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
//Save modified data
|
|
TESTC_(RowsetA.GetRowData(rghRow[ROW_THREE],&pModifiedData),S_OK) //save row 3 new data;
|
|
|
|
//Update
|
|
TESTC_(RowsetA.UpdateRow(NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[3]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[4]==DBROWSTATUS_E_DELETED);
|
|
|
|
//Verify Update did update the data at the backend
|
|
// TESTC(RowsetA.CompareTableData(FIRST_ROW, rghRow[ROW_ONE]));
|
|
// TESTC(RowsetA.CompareTableData(THIRD_ROW, rghRow[ROW_THREE]));
|
|
|
|
//Verify Update did update the data in the rowset
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_THREE],pModifiedData));
|
|
|
|
//Verify Updated data does not equal orginal data
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_THREE],pOriginalData));
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
|
|
PROVIDER_FREE(rgRowStatus);
|
|
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pModifiedData);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 1 hard deleted / 1 invalid / 1 soft-del
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_13()
|
|
{
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(SECOND_ROW, TWO_ROWS, rghRow),S_OK);
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_ONE]),S_OK) //hard-delete row 1;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //soft-delete row 2;
|
|
rghRow[ROW_THREE] = DB_NULL_HROW; //invalid row 3
|
|
rghRow[ROW_FOUR] = rghRow[ROW_ONE]; //duplicate row 4 == row 1
|
|
|
|
TESTC_(RowsetA.UpdateRow(NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_E_INVALID);
|
|
TESTC(rgRowStatus[3]==DBROWSTATUS_E_DELETED);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(TWO_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 1 hard deleted / 1 invalid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_14()
|
|
{
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(SECOND_ROW, &rghRow[ROW_ONE]),S_OK);
|
|
rghRow[ROW_TWO] = DB_NULL_HROW; //invalid row 2
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_ONE]),S_OK) //hard-delete row 1;
|
|
|
|
TESTC_(RowsetA.UpdateRow(NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_E_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_E_INVALID);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 1 col with non-schema info
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_15()
|
|
{
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
const int NROWS = ONE_ROW;
|
|
HROW rghRow[NROWS] = {NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(SECOND_ROW, &rghRow[ROW_ONE]),S_OK);
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_ONE]),S_OK) //hard-delete row 1;
|
|
|
|
TESTC_(RowsetA.UpdateRow(NROWS,rghRow,NULL,NULL,&rgRowStatus),DB_E_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 col with metacolumn non-schema info
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_16()
|
|
{
|
|
const int NROWS = ONE_ROW;
|
|
HROW rghRow[NROWS] = {NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &rghRow[ROW_ONE]),S_OK);
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_ONE]),S_OK) //hard-delete row 1;
|
|
|
|
TESTC_(RowsetA.UpdateRow(NROWS,rghRow,NULL,NULL,NULL),DB_E_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 2 inserted rows, no value specified / not nullable
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_17()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
DBCOUNTITEM cInsertedRows = 0;
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_ONE]),S_OK);
|
|
cInsertedRows++;
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK);
|
|
cInsertedRows++;
|
|
}
|
|
|
|
//These are valid inserted rows, with defaults
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_TWO]),S_OK);
|
|
cInsertedRows++;
|
|
}
|
|
if(RowsetA.AllowPendingRows(4))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK);
|
|
cInsertedRows++;
|
|
}
|
|
|
|
TESTC_(RowsetA.UpdateRow(0,NULL,&cUpdatedRows,&rgUpdatedRows),S_OK);
|
|
TESTC(cUpdatedRows==cInsertedRows);
|
|
TESTC(rgUpdatedRows[0]==rghRow[ROW_ONE]);
|
|
if(cInsertedRows >= 2)
|
|
TESTC(rgUpdatedRows[1]==rghRow[ROW_THREE]);
|
|
if(cInsertedRows >= 3)
|
|
TESTC(rgUpdatedRows[2]==rghRow[ROW_TWO]);
|
|
if(cInsertedRows >= 4)
|
|
TESTC(rgUpdatedRows[3]==rghRow[ROW_FOUR]);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS,rghRow);
|
|
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_18()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Update a non-updateable column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_19()
|
|
{
|
|
HACCESSOR hAccessorAllCol = NULL;
|
|
DBLENGTH cRowSize = 0;
|
|
DBORDINAL cAllBindings = 0;
|
|
DBORDINAL cUpdBindings = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
void* pData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the hAccessor bindings for all col, even non-updateable columns
|
|
TESTC_(GetAccessorAndBindings(RowsetA(), DBACCESSOR_ROWDATA,
|
|
&hAccessorAllCol, NULL, &cAllBindings, &cRowSize, DBPART_ALL, ALL_COLS_BOUND),S_OK);
|
|
|
|
//Obtain the hAccessor bindings for all updateable columns
|
|
TESTC_(GetAccessorAndBindings(RowsetA(), DBACCESSOR_ROWDATA,
|
|
NULL, NULL, &cUpdBindings, NULL, DBPART_ALL, UPDATEABLE_COLS_BOUND),S_OK);
|
|
|
|
//If all columns are updateable, there is nothing to test for this variation
|
|
if(cUpdBindings == cAllBindings)
|
|
goto CLEANUP;
|
|
|
|
//Alloc buffer large enough for all columns
|
|
pData = PROVIDER_ALLOC(sizeof(void*)*cRowSize);
|
|
|
|
//Get row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
//Get Data
|
|
TESTC_(RowsetA()->GetData(hRow,hAccessorAllCol,pData),S_OK);
|
|
//Release the row handle
|
|
TESTC_(RowsetA.ReleaseRows(hRow),S_OK);
|
|
|
|
//Insert a new row, containing non-updateable columns
|
|
//Its provider specific wither can can insert any other the other columns
|
|
hRow = NULL;
|
|
hr = RowsetA.pIRowsetUpdate()->InsertRow(NULL,hAccessorAllCol,pData,&hRow);
|
|
TEST2C_(hr, DB_S_ERRORSOCCURRED, DB_E_ERRORSOCCURRED);
|
|
|
|
//Try Updating the row, containing non-updateable columns
|
|
TESTC_(RowsetA.UpdateRow(ONE_ROW,&hRow,NULL,NULL,&rgRowStatus),DB_E_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
if(hr==DB_S_ERRORSOCCURRED)
|
|
{
|
|
//If we got a success code from InsertRow, then the hRow returned should be valid
|
|
//And passing a valid hRow to Update should fail since not all are updatable
|
|
TESTC(hRow != NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_E_INTEGRITYVIOLATION);
|
|
}
|
|
else
|
|
{
|
|
//If we got a failure code from InsertRow, then the hRow returned should be NULL
|
|
//And passing a NULL hRow to Update should fail
|
|
TESTC(hRow == NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_E_INVALID);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
|
|
PROVIDER_FREE(rgRowStatus);
|
|
PROVIDER_FREE(pData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Delete a non-updateable column
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_20()
|
|
{
|
|
HACCESSOR hAccessorAllCol = NULL;
|
|
DBLENGTH cRowSize = 0;
|
|
DBORDINAL cAllBindings = 0;
|
|
DBORDINAL cUpdBindings = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
void* pData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain the hAccessor bindings for all col, even non-updateable columns
|
|
TESTC_(GetAccessorAndBindings(RowsetA(), DBACCESSOR_ROWDATA,
|
|
&hAccessorAllCol, NULL, &cAllBindings, &cRowSize, DBPART_ALL, ALL_COLS_BOUND),S_OK);
|
|
|
|
//Obtain the hAccessor bindings for all updateable columns
|
|
TESTC_(GetAccessorAndBindings(RowsetA(), DBACCESSOR_ROWDATA,
|
|
NULL, NULL, &cUpdBindings, NULL, DBPART_ALL, UPDATEABLE_COLS_BOUND),S_OK);
|
|
|
|
//Depending upon the DataSource all columns might be updateable
|
|
//If all columns are updateable, there is nothing to test for this variation
|
|
if(cUpdBindings == cAllBindings)
|
|
goto CLEANUP;
|
|
|
|
//Alloc buffer large enough for all columns
|
|
pData = PROVIDER_ALLOC(sizeof(void*)*cRowSize);
|
|
|
|
//Get row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,THREE_ROWS,rghRow),S_OK);
|
|
|
|
//Get Data
|
|
TESTC_(RowsetA()->GetData(rghRow[ROW_TWO],hAccessorAllCol,pData),S_OK);
|
|
//Insert a new row, containing non-updateable columns
|
|
//Its provider specific wither can can insert any other the other columns
|
|
hr = RowsetA.pIRowsetUpdate()->InsertRow(NULL,hAccessorAllCol,pData,&rghRow[ROW_FOUR]);
|
|
TEST2C_(hr, DB_S_ERRORSOCCURRED, DB_E_ERRORSOCCURRED);
|
|
//Now update backend
|
|
TESTC_(RowsetA.UpdateRow(rghRow[ROW_FOUR]),DB_E_ERRORSOCCURRED);
|
|
|
|
//Try deleting non-updateable row
|
|
TESTC_(RowsetA.pIRowsetUpdate()->DeleteRows(NULL,ONE_ROW,&rghRow[ROW_FOUR],NULL), hr==DB_S_ERRORSOCCURRED ? S_OK : DB_E_ERRORSOCCURRED);
|
|
|
|
//Now Try Updating the rows, containing non-updateable columns
|
|
TESTC_(RowsetA.UpdateRow(FOUR_ROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[1]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[2]==DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[3]==(DBROWSTATUS)(hr==DB_S_ERRORSOCCURRED ? DBROWSTATUS_E_DELETED : DBROWSTATUS_E_INVALID));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
RowsetA.ReleaseAccessor(hAccessorAllCol);
|
|
|
|
PROVIDER_FREE(pData);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Deferred only
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_21()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
void* pOriginalData = NULL;
|
|
void* pBackEndData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_DEFERRED);
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Make changes to the backend
|
|
//TODO
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Verify Seen with GetOriginalData
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &pOriginalData),S_OK);
|
|
//TESTC(RowsetA.CompareRowData(&pOriginalData, &pBackEndData));
|
|
|
|
//Make changes to the backend again
|
|
//TODO
|
|
|
|
//Verify Not Seen with GetOriginalData
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &pOriginalData),S_OK);
|
|
//TESTC(!RowsetA.CompareRowData(&pOriginalData, &pBackEndData));
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pBackEndData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Cache-Deferred only
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_22()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
void* pOriginalData = NULL;
|
|
void* pBackEndData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_CACHEDEFERRED);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Make changes to the backend
|
|
//TODO
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Verify Seen with GetOriginalData
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &pOriginalData),S_OK);
|
|
//TESTC(RowsetA.CompareRowData(&pOriginalData, &pBackEndData));
|
|
|
|
//Make changes to the backend again
|
|
//TODO
|
|
|
|
//Verify Not Seen with GetOriginalData
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &pOriginalData),S_OK);
|
|
//TESTC(!RowsetA.CompareRowData(&pOriginalData, &pBackEndData));
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pBackEndData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Cache-Deferred / Deferred / Non-deferred col
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_23()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
void* pOriginalData = NULL;
|
|
void* pBackEndData = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_DEFERRED);
|
|
RowsetA.SetSettableProperty(DBPROP_CACHEDEFERRED);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Make changes to the backend
|
|
//TODO
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Verify Seen with GetOriginalData
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &pOriginalData),S_OK);
|
|
//TESTC(RowsetA.CompareRowData(&pOriginalData, &pBackEndData));
|
|
|
|
//Make changes to the backend again
|
|
//TODO
|
|
|
|
//Verify Not Seen with GetOriginalData
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_ONE], &pOriginalData),S_OK);
|
|
//TESTC(!RowsetA.CompareRowData(&pOriginalData, &pBackEndData));
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(pOriginalData);
|
|
PROVIDER_FREE(pBackEndData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_24()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Duplicate hrow entries in the array
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_25()
|
|
{
|
|
TBEGIN
|
|
HROW rghRow[FIVE_ROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
|
|
ULONG cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, TWO_ROWS, rghRow),S_OK);
|
|
rghRow[ROW_THREE] = rghRow[ROW_ONE]; // Duplicate hRow, hRow1 == hRow3
|
|
rghRow[ROW_FOUR] = rghRow[ROW_TWO]; // Duplicate hRow, hRow2 == hRow4
|
|
|
|
//Now make some changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //delete row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //delete row 1 //Duplicate...;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK) //delete row 3;
|
|
if(RowsetA.AllowPendingRows(4))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK) //delete row 3 //Duplicate...;
|
|
if(RowsetA.AllowPendingRows(5))
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FIVE]),S_OK) //insert row 5;
|
|
|
|
TESTC_(RowsetA.UpdateRow(FIVE_ROWS,rghRow), RowsetA.AllowPendingRows(5) ? S_OK : DB_S_ERRORSOCCURRED);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FIVE_ROWS,rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Fetch/Modify/Release
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_26()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Now make some changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
cModifiedRows++;
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //delete row 2;
|
|
cModifiedRows++;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4;
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Now release handles
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
|
|
TESTC_(RowsetA.UpdateRow(0,NULL,&cUpdatedRows,&rgUpdatedRows),S_OK);
|
|
TESTC(cUpdatedRows==cModifiedRows && rgUpdatedRows!=NULL);
|
|
COMPC(rgUpdatedRows[0],rghRow[ROW_ONE])
|
|
if(cModifiedRows >=2 )
|
|
COMPC(rgUpdatedRows[1],rghRow[ROW_TWO])
|
|
if(cModifiedRows >=3 )
|
|
COMPC(rgUpdatedRows[2],rghRow[ROW_FOUR])
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS,rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Fetch/Modify/don't Release
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_27()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Now make some changes
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4;
|
|
|
|
//Don't release handles
|
|
TESTC_(RowsetA.UpdateRow(0,NULL,&cUpdatedRows,&rgUpdatedRows),S_OK);
|
|
TESTC(cUpdatedRows==ONE_ROW);
|
|
COMPC(rgUpdatedRows[0],rghRow[ROW_FOUR])
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS,rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_28()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Accessor - BLOB / Long columns - SetPos
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_29()
|
|
{
|
|
TBEGIN
|
|
TRETURN //TODO need to work on blob support once supported
|
|
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
HROW hNewRow = DB_NULL_HROW;
|
|
DBLENGTH cRowSize = 0;
|
|
|
|
void* pInsertData = NULL;
|
|
void* pModifyData = NULL;
|
|
|
|
void* pData1 = NULL;
|
|
void* pData2 = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetLocate);
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Create Accessor binding BLOB/Long data (last param TRUE)
|
|
TESTC_(GetAccessorAndBindings(RowsetA(),DBACCESSOR_ROWDATA,&hAccessor,
|
|
NULL,NULL,&cRowSize,DBPART_ALL,UPDATEABLE_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_NOTPARAM, BLOB_LONG), S_OK);
|
|
|
|
//Alloc buffers
|
|
TESTC(RowsetA.MakeRowData(&pInsertData,hAccessor));
|
|
TESTC(RowsetA.MakeRowData(&pModifyData,hAccessor));
|
|
pData1 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
pData2 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
|
|
//Get Rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Get the Data
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData1),S_OK);
|
|
|
|
//Modify a row (BLOB data)
|
|
TESTC_(RowsetA.pIRowsetChange()->SetData(rghRow[ROW_ONE],hAccessor, pModifyData),S_OK);
|
|
//Delete a row (BLOB data)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Before update, should not be equal
|
|
TESTC(!RowsetA.CompareRowData(pData1, pModifyData, hAccessor));
|
|
|
|
//Now call Update
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//After update, should be equal
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData2),S_OK);
|
|
TESTC(RowsetA.CompareRowData(pData2, pModifyData, hAccessor));
|
|
|
|
|
|
CLEANUP:
|
|
//Free Data
|
|
RowsetA.ReleaseRowData(pInsertData,hAccessor);
|
|
RowsetA.ReleaseRowData(pModifyData,hAccessor);
|
|
|
|
//Release the Accesssor
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
|
|
PROVIDER_FREE(pData1);
|
|
PROVIDER_FREE(pData2);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Accessor - BLOB / Long columns - QBU
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_30()
|
|
{
|
|
TBEGIN
|
|
TRETURN //TODO need to work on blob support once supported
|
|
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
HROW hNewRow = DB_NULL_HROW;
|
|
DBLENGTH cRowSize = 0;
|
|
|
|
void* pInsertData = NULL;
|
|
void* pModifyData = NULL;
|
|
|
|
void* pData1 = NULL;
|
|
void* pData2 = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetLocate);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Create Accessor binding BLOB/Long data (last param TRUE)
|
|
TESTC_(GetAccessorAndBindings(RowsetA(),DBACCESSOR_ROWDATA,&hAccessor,
|
|
NULL,NULL,&cRowSize,DBPART_ALL,UPDATEABLE_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_EMPTY,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_NOTPARAM, BLOB_LONG), S_OK);
|
|
|
|
//Alloc buffers
|
|
TESTC(RowsetA.MakeRowData(&pInsertData,hAccessor));
|
|
TESTC(RowsetA.MakeRowData(&pModifyData,hAccessor));
|
|
pData1 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
pData2 = PROVIDER_ALLOC(sizeof(pInsertData));
|
|
|
|
//Get Rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Get the Data
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData1),S_OK);
|
|
|
|
//Modify a row (BLOB data)
|
|
TESTC_(RowsetA.pIRowsetChange()->SetData(rghRow[ROW_ONE],hAccessor, pModifyData),S_OK);
|
|
//Delete a row (BLOB data)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
//Insert a row (BLOB data)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.pIRowsetChange()->InsertRow(NULL,hAccessor, pInsertData, &hNewRow),S_OK);
|
|
|
|
//Before update, should not be equal
|
|
TESTC(!RowsetA.CompareRowData(pData1, pModifyData, hAccessor));
|
|
|
|
//Now call Update
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//After update, should be equal
|
|
TESTC_(RowsetA.pIRowset()->GetData(rghRow[ROW_ONE], hAccessor, pData2),S_OK);
|
|
TESTC(RowsetA.CompareRowData(pData2, pModifyData, hAccessor));
|
|
|
|
|
|
CLEANUP:
|
|
//Free Data
|
|
RowsetA.ReleaseRowData(pInsertData,hAccessor);
|
|
RowsetA.ReleaseRowData(pModifyData,hAccessor);
|
|
|
|
//Release the Accesssor
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hNewRow);
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
|
|
PROVIDER_FREE(pData1);
|
|
PROVIDER_FREE(pData2);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_31()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Related - Resync / GetOriginalData same data
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_32()
|
|
{
|
|
TBEGIN
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
void* pOriginalData = NULL;
|
|
void* pResynchData = NULL;
|
|
IRowsetResynch* pIRowsetResynch = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetResynch);//Requires RESYNCH
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Alloc pData
|
|
pResynchData = PROVIDER_ALLOC(sizeof(void*)*RowsetA.m_cRowSize);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Now make some changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4;
|
|
|
|
//Call GetOriginalData for row 3
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_THREE], &pOriginalData),S_OK);
|
|
|
|
//Obtain the Resynch Interface
|
|
TESTC_(QI(RowsetA(),IID_IRowsetResynch,(void**)&pIRowsetResynch),S_OK);
|
|
|
|
//Call Resynch::GetVisisableData for Row 3
|
|
TESTC_(pIRowsetResynch->GetVisibleData(rghRow[ROW_THREE],RowsetA.m_hAccessor,pResynchData),S_OK);
|
|
|
|
//Verify GetOriginalData == GetVisibleData
|
|
TESTC(RowsetA.CompareRowData(pOriginalData, pResynchData));
|
|
|
|
//Call Update
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//Verify GetOriginalData == GetVisibleData after update
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_TWO], &pOriginalData),S_OK);
|
|
TESTC_(pIRowsetResynch->GetVisibleData(rghRow[ROW_TWO],RowsetA.m_hAccessor,pResynchData),S_OK);
|
|
TESTC(RowsetA.CompareRowData(pOriginalData, pResynchData));
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS,rghRow);
|
|
SAFE_RELEASE(pIRowsetResynch);
|
|
PROVIDER_FREE(pResynchData);
|
|
PROVIDER_FREE(pOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(33)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Related - ResynchRows
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_33()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
void* pOriginalData = NULL;
|
|
IRowsetResynch* pIRowsetResynch = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetResynch);//Requires RESYNCH
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Now make some changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4;
|
|
|
|
//Call GetOriginalData for row 3
|
|
TESTC_(RowsetA.GetOriginalData(rghRow[ROW_THREE], &pOriginalData),S_OK);
|
|
|
|
//Verify GetOriginalData != Rowset after changes
|
|
TESTC(!RowsetA.CompareRowData(rghRow[ROW_THREE], pOriginalData));
|
|
|
|
//Obtain the Resynch Interface
|
|
TESTC_(QI(RowsetA(),IID_IRowsetResynch,(void**)&pIRowsetResynch),S_OK);
|
|
|
|
//Call Resynch::ResynchRows for all rows
|
|
TESTC_(pIRowsetResynch->ResynchRows(0,NULL,NULL,NULL,NULL),DB_S_ERRORSOCCURRED);
|
|
|
|
//Verify GetOriginalData == GetVisibleData
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_THREE], pOriginalData));
|
|
|
|
//Call Update
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//Verify GetOriginalData == GetVisibleData after update
|
|
TESTC(RowsetA.CompareRowData(rghRow[ROW_THREE], pOriginalData));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS,rghRow);
|
|
SAFE_RELEASE(pIRowsetResynch);
|
|
PROVIDER_FREE(pOriginalData);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(34)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Related - Modify / Resync
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_34()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
void* pOriginalData = NULL;
|
|
IRowsetResynch* pIRowsetResynch = NULL;
|
|
|
|
DBCOUNTITEM cRowsResynched = 1;
|
|
HROW* rgRowsResynched = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetResynch); //Requires RESYNCH
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Now make some changes
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4;
|
|
cModifiedRows++;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
cModifiedRows++;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//GetPendingRows == 3
|
|
TESTC_(RowsetA.GetPendingRows(cModifiedRows),S_OK);
|
|
|
|
//Obtain the Resynch Interface
|
|
TESTC_(QI(RowsetA(),IID_IRowsetResynch,(void**)&pIRowsetResynch),S_OK);
|
|
|
|
//Call Resynch::ResynchRows for all rows
|
|
//Should return DB_S for newly inserted rows
|
|
TESTC_(pIRowsetResynch->ResynchRows(0,NULL,&cRowsResynched,&rgRowsResynched,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
|
|
//Verify Resynch output params
|
|
TESTC(cRowsResynched==FOUR_ROWS) //All "Active" rows;
|
|
TESTC(rgRowsResynched!=NULL && rgRowStatus!=NULL);
|
|
|
|
//ResynchRows resycnhs all active rows, so any retrieved or intered row is game
|
|
//Thats why even though only 3 rows have been changed, 4 are returned...
|
|
TESTC(rgRowsResynched[3] == rghRow[ROW_FOUR]);
|
|
TESTC(rgRowStatus[3] == DBROWSTATUS_E_PENDINGINSERT);
|
|
if(cModifiedRows >= 2)
|
|
{
|
|
TESTC(rgRowsResynched[1] == rghRow[ROW_TWO]);
|
|
TESTC(rgRowStatus[1] == DBROWSTATUS_S_OK);
|
|
}
|
|
if(cModifiedRows >= 3)
|
|
{
|
|
TESTC(rgRowsResynched[2] == rghRow[ROW_THREE]);
|
|
TESTC(rgRowStatus[2] == DBROWSTATUS_S_OK);
|
|
}
|
|
if(cModifiedRows >= 4)
|
|
{
|
|
TESTC(rgRowsResynched[0] == rghRow[ROW_ONE]);
|
|
TESTC(rgRowStatus[0] == DBROWSTATUS_S_OK);
|
|
}
|
|
|
|
|
|
//GetPendingRows, should be ONE after resync, there was a newly inserted row
|
|
TESTC_(RowsetA.GetPendingRows(ONE_ROW),S_OK);
|
|
|
|
//Update All, no updates
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
RowsetA.ReleaseRows(cRowsResynched,rgRowsResynched);
|
|
SAFE_RELEASE(pIRowsetResynch);
|
|
PROVIDER_FREE(pOriginalData);
|
|
|
|
PROVIDER_FREE(rgRowsResynched);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(35)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Related - Modify / Resync / Undo
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_35()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = ONE_ROW;
|
|
HROW rghRow[NROWS] = {NULL};
|
|
IRowsetResynch* pIRowsetResynch = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_IRowsetResynch);//Requires RESYNCH
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, ONE_ROW, rghRow),S_OK);
|
|
|
|
//Now make some changes
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK) //insert row 4;
|
|
|
|
//GetPendingRows == 1
|
|
TESTC_(RowsetA.GetPendingRows(ONE_ROW),S_OK);
|
|
|
|
//Obtain the Resynch Interface
|
|
TESTC_(QI(RowsetA(),IID_IRowsetResynch,(void**)&pIRowsetResynch),S_OK);
|
|
|
|
//Call Resynch::ResynchRows for all rows
|
|
//Should return DB_S for newly inserted rows
|
|
TESTC_(pIRowsetResynch->ResynchRows(0,NULL,NULL,NULL,NULL),DB_S_ERRORSOCCURRED);
|
|
|
|
//GetPendingRows, should be ONE after resync, there was a newly inserted row
|
|
TESTC_(RowsetA.GetPendingRows(ONE_ROW),S_OK);
|
|
|
|
//Undo all
|
|
TESTC_(RowsetA.UndoAll(),S_OK);
|
|
|
|
//GetPendingRows
|
|
TESTC_(RowsetA.GetPendingRows(NO_ROWS),S_FALSE);
|
|
|
|
//Update All
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//GetPendingRows
|
|
TESTC_(RowsetA.GetPendingRows(NO_ROWS),S_FALSE);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
SAFE_RELEASE(pIRowsetResynch);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(36)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_36()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(37)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - NONE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_37()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set no OWN/OTHER properties
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(38)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OWNINSERT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_38()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OWNINSERT properties
|
|
if(!MSDASQL) RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
if(!MSDASQL) RowsetB.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(39)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OWNINSERT & CANSCROLL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_39()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OWNINSERTT & CANSCROLL properties
|
|
if(!MSDASQL) RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetA.SetSettableProperty(DBPROP_CANSCROLLBACKWARDS);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
if(!MSDASQL) RowsetB.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetB.SetSettableProperty(DBPROP_CANSCROLLBACKWARDS);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(40)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OWNUPDATEDELETE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_40()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OWNUPDATEDELETE properties
|
|
RowsetA.SetSettableProperty(DBPROP_OWNUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(DBPROP_OWNUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(41)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OWNUPDATEDELETE & CANFETCH
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_41()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OWNUPDATEDELETE & CANFETCH properties
|
|
RowsetA.SetSettableProperty(DBPROP_OWNUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(DBPROP_CANFETCHBACKWARDS);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(DBPROP_OWNUPDATEDELETE);
|
|
RowsetB.SetSettableProperty(DBPROP_CANFETCHBACKWARDS);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(42)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OTHERINSERT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_42()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OTHERINSERT properties
|
|
if(!MSDASQL) RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
if(!MSDASQL) RowsetB.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(43)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OTHERINSERT & CANSCROLL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_43()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OTHERINSERT & CANSCROLL properties
|
|
if(!MSDASQL) RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetA.SetSettableProperty(DBPROP_CANSCROLLBACKWARDS);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
if(!MSDASQL) RowsetB.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetB.SetSettableProperty(DBPROP_CANSCROLLBACKWARDS);
|
|
RowsetB.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(44)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OTHERUPDATEDELETE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_44()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OTHERUPDATEDELETE properties
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(45)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OTHERUPDATEDELETE & CANSCROLL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_45()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OTHERUPDATEDELETE & CANSCROLL properties
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(DBPROP_CANSCROLLBACKWARDS);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetB.SetSettableProperty(DBPROP_CANSCROLLBACKWARDS);
|
|
RowsetB.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(46)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OWNUPDATEDELETE & OTHERINSERT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_46()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OTHERUPDATEDELETE & OTHRINSERT properties
|
|
RowsetA.SetSettableProperty(DBPROP_OWNUPDATEDELETE);
|
|
if(!MSDASQL) RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(DBPROP_OWNUPDATEDELETE);
|
|
if(!MSDASQL) RowsetB.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(47)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OWNUPDATEDELETE & OTHERINSERT & CANFETCH
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_47()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OWNUPDATEDELETE & OTHRINSERT & CANFETCH properties
|
|
RowsetA.SetSettableProperty(DBPROP_OWNUPDATEDELETE);
|
|
if(!MSDASQL) RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetA.SetSettableProperty(DBPROP_CANFETCHBACKWARDS);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(DBPROP_OWNUPDATEDELETE);
|
|
if(!MSDASQL) RowsetB.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetB.SetSettableProperty(DBPROP_CANFETCHBACKWARDS);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(48)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OTHERUPDATEDELETE & OWNINSERT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_48()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OTHERUPDATEDELETE & OWNINSERT properties
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
if(!MSDASQL) RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
if(!MSDASQL) RowsetB.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(49)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - OTHERUPDATEDELETE & OWNINSERT & CANSCROLL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_49()
|
|
{
|
|
TBEGIN
|
|
HROW hNewRowA = NULL;
|
|
HROW hFirstRowA= NULL;
|
|
|
|
HROW hNewRowB = NULL;
|
|
HROW hFirstRowB= NULL;
|
|
|
|
CRowsetUpdate RowsetA, RowsetB;
|
|
|
|
//Set OTHERUPDATEDELETE & OWNINSERT & CANSCROLL properties
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
if(!MSDASQL) RowsetA.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetA.SetSettableProperty(DBPROP_CANSCROLLBACKWARDS);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
RowsetB.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
if(!MSDASQL) RowsetB.SetSettableProperty(DBPROP_OTHERINSERT);
|
|
RowsetB.SetSettableProperty(DBPROP_CANSCROLLBACKWARDS);
|
|
RowsetB.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetB.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//2 Rowsets, A and B
|
|
//A fetches/deletes the first row
|
|
//B modifies last row
|
|
//A inserts a new row
|
|
//B inserts a new row, Updates
|
|
//A Updates
|
|
|
|
//A fetches and deletes the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hFirstRowA),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(hFirstRowA),S_OK); //Will Return DBROWSTATUS_S_PENDINGCHANGES;
|
|
|
|
//B modifies the first row, make sure no conflict between A's row
|
|
TESTC_(RowsetB.GetRow(FIRST_ROW,&hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.DeleteRow(hFirstRowB),S_OK);
|
|
|
|
//A inserts a new row
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.InsertRow(&hNewRowA),S_OK);
|
|
|
|
//B inserts a new row, Updates
|
|
if(RowsetB.AllowPendingRows(2))
|
|
TESTC_(RowsetB.InsertRow(&hNewRowB),S_OK);
|
|
TESTC_(RowsetB.UndoRow(hFirstRowB),S_OK);
|
|
TESTC_(RowsetB.UpdateAll(),S_OK);
|
|
|
|
//A Updates, row should already been deleted
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hNewRowA);
|
|
RowsetA.ReleaseRows(hFirstRowA);
|
|
RowsetB.ReleaseRows(hNewRowB);
|
|
RowsetB.ReleaseRows(hFirstRowB);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(50)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - verify property dependencies
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_50()
|
|
{
|
|
TBEGIN
|
|
CRowset RowsetA;
|
|
|
|
//Set Properties
|
|
RowsetA.SetProperty(DBPROP_IRowsetUpdate);
|
|
RowsetA.SetProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetProperty(DBPROP_OWNUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Just as a sanity check, make sure IID_IRowseUpdate is still set
|
|
TESTC(RowsetA.GetProperty(DBPROP_IRowsetUpdate));
|
|
|
|
//Verify IID_IRowsetChange is implicitly set
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_IRowsetChange));
|
|
|
|
//Just as a sanity check, make sure still set
|
|
TESTC(RowsetA.GetProperty(DBPROP_OTHERUPDATEDELETE));
|
|
|
|
//Just as a sanity check, make sure still set
|
|
TESTC(RowsetA.GetProperty(DBPROP_OWNUPDATEDELETE));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(51)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_51()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(52)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Related - Qualified Table Name
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_52()
|
|
{
|
|
CRowsetUpdate RowsetA;
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
//Use the Qualified table name,
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make change(s)
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//Update the row
|
|
TESTC_(RowsetA.UpdateRow(hRow),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(53)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_53()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(54)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - MAXPENDINGCHANGEROWS
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_54()
|
|
{
|
|
TBEGIN
|
|
const ULONG NROWS = 7;
|
|
HROW rghRow[NROWS];
|
|
HROW rghNewRow[NROWS];
|
|
|
|
ULONG_PTR ulMaxPendingRows = 0;
|
|
ULONG_PTR i, ulMaxOpenRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
RowsetA.GetProperty(DBPROP_MAXPENDINGROWS, DBPROPSET_ROWSET, &ulMaxPendingRows);
|
|
RowsetA.GetProperty(DBPROP_MAXOPENROWS, DBPROPSET_ROWSET, &ulMaxOpenRows);
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(NROWS));
|
|
|
|
//Besides just stress testing the number of pendingrows and open rows,
|
|
//I'm also going to stress test the internal imp of the update array.
|
|
//Their keeping an internal array of the modified rows, and upon deleting
|
|
//some they will compact the array. So this should be stress tested here...
|
|
|
|
//Grab all the rows of the table, starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Modify every even row
|
|
for(i=0; i<NROWS; i+=2)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[i]),S_OK);
|
|
//GetPendingRows, should be half pending
|
|
TESTC_(RowsetA.GetPendingRows(NROWS/2+1),S_OK);
|
|
|
|
//Update just those even rows, should be no change
|
|
for(i=0; i<NROWS; i+=2)
|
|
TESTC_(RowsetA.UpdateRow(rghRow[i]),S_OK);
|
|
//GetPendingRows, should be no pending
|
|
TESTC_(RowsetA.GetPendingRows(NO_ROWS),S_FALSE);
|
|
|
|
//Now delete all the odd rows
|
|
for(i=1; i<NROWS; i+=2)
|
|
TESTC_(RowsetA.DeleteRow(rghRow[i]),S_OK);
|
|
//GetPendingRows, should be half pending
|
|
TESTC_(RowsetA.GetPendingRows(NROWS/2),S_OK);
|
|
|
|
//Now Undo all the odd rows
|
|
for(i=1; i<NROWS; i+=2)
|
|
TESTC_(RowsetA.UndoRow(rghRow[i]),S_OK);
|
|
//GetPendingRows, should be no pending
|
|
TESTC_(RowsetA.GetPendingRows(NO_ROWS),S_FALSE);
|
|
|
|
|
|
//Now Insert a bunch of rows
|
|
for(i=0; i<NROWS; i++)
|
|
TESTC_(RowsetA.InsertRow(&rghNewRow[i]),S_OK);
|
|
|
|
//Now Modify all the odd inserted rows
|
|
for(i=1; i<NROWS; i+=2)
|
|
TESTC_(RowsetA.ModifyRow(rghNewRow[i]),S_OK);
|
|
//GetPendingRows, should be all pending
|
|
TESTC_(RowsetA.GetPendingRows(NROWS),S_OK);
|
|
|
|
//Now delete all the even inserted rows
|
|
for(i=0; i<NROWS; i+=2)
|
|
TESTC_(RowsetA.DeleteRow(rghNewRow[i]),S_OK);
|
|
//GetPendingRows, should be all (half modified / half deleted)
|
|
TESTC_(RowsetA.GetPendingRows(NROWS/2),S_OK);
|
|
|
|
//Now Update all odd
|
|
for(i=1; i<NROWS; i+=2)
|
|
TESTC_(RowsetA.UpdateRow(rghNewRow[i]),S_OK);
|
|
//GetPendingRows, should be half pending
|
|
TESTC_(RowsetA.GetPendingRows(NO_ROWS),S_FALSE);
|
|
|
|
//Update all
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
//GetPendingRows, should be no pending
|
|
TESTC_(RowsetA.GetPendingRows(NO_ROWS),S_FALSE);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
RowsetA.ReleaseRows(NROWS, rghNewRow);
|
|
TableInsert(NROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(55)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - CANHOLDROWS
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_55()
|
|
{
|
|
TBEGIN
|
|
HROW rghRow[TWO_ROWS] = {NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Fetch/modify row 1
|
|
//Fetch last row
|
|
//Delete row 1 and Undo
|
|
//Update all
|
|
|
|
//Fetch Row 1, and modify
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
|
|
//Fetch Next row
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Delete Row 1, and Undo
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.UndoRow(rghRow[ROW_ONE]),S_OK);
|
|
|
|
//Modify other row and release
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(rghRow[ROW_ONE]),S_OK);
|
|
|
|
//Update all
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(TWO_ROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(56)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - ~CANHOLDROWS
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_56()
|
|
{
|
|
DBCOUNTITEM cRowsObtained=1;
|
|
HROW* rgRowsObtained = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
HROW hFirstRow = NULL;
|
|
HROW hLastRow = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetProperty(DBPROP_CANHOLDROWS,DBPROPSET_ROWSET,(void*)VARIANT_FALSE,DBTYPE_BOOL);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Setting CANHOLROWS=FALSE, According to the spec indicates that holding rows may or
|
|
//may not be allowed, since you didn't request the ability to hold rows. Prevents the
|
|
//provider from having artifical limiting functionality.
|
|
|
|
//Verify ~CANHOLDROWS
|
|
TESTC(!RowsetA.GetProperty(DBPROP_CANHOLDROWS));
|
|
|
|
//Fetch Row 1, and modify
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hFirstRow),S_OK);
|
|
TESTC_(RowsetA.ModifyRow(hFirstRow),S_OK);
|
|
|
|
//Fetch Second row, "may" cause an error
|
|
TEST3C_(hr = RowsetA()->GetNextRows(NULL, SECOND_ROW, ONE_ROW, &cRowsObtained, &rgRowsObtained), S_OK, DB_S_ROWLIMITEXCEEDED, DB_E_ROWSNOTRELEASED);
|
|
|
|
if(hr == S_OK)
|
|
{
|
|
//Able to hold row when CANHOLDROWS = FALSE
|
|
TESTC(cRowsObtained==1 && rgRowsObtained!=NULL && rgRowsObtained[0]!=NULL);
|
|
}
|
|
else if(hr == DB_S_ROWLIMITEXCEEDED)
|
|
{
|
|
//Unable to have more than 1 row open
|
|
TESTC(cRowsObtained==0 && rgRowsObtained==NULL);
|
|
TESTC(RowsetA.m_ulMaxOpenRows == 1);
|
|
}
|
|
else
|
|
{
|
|
//Unable to hold rows when CANHOLDROWS = FALSE
|
|
TESTC(cRowsObtained==0 && rgRowsObtained==NULL);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hFirstRow);
|
|
RowsetA.ReleaseRows(hLastRow);
|
|
RowsetA.ReleaseRows(cRowsObtained, rgRowsObtained);
|
|
PROVIDER_FREE(rgRowsObtained);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(57)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - BOOKMARKS
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_57()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(58)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_58()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(59)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - Insert/Commit
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_59()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(60)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - Insert/Commit/Update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_60()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(61)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - Modify/Update/Commit
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_61()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(62)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - Modify/Update/Commit/Undo
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_62()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(63)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - Delete/Update/Abort
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_63()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(64)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - Delete/Update/Abort/Undo
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_64()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(65)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - concurrency - DB_E_CONCURRENCYVILOATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_65()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(66)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - ABORTRETAINING
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_66()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(67)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - ~ABORTRETAINING
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_67()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(68)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - COMMITRETAINING
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_68()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(69)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - ~COMMITRETAINING
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_69()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(70)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - NOTENTRANT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_70()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(71)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_71()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(72)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Insert/Modify/Delete a single row
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_72()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
|
|
DBCOUNTITEM cPendingRows = 1;
|
|
HROW* rgPendingRows;
|
|
DBROWSTATUS* rgPendingStatus = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK) //insert row X;
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK) //modify row X;
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK) //delete row X;
|
|
|
|
//inv: Should be no changes that need updating.
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,&rgPendingStatus),S_FALSE);
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
//inv: Should not be any updates to the backend
|
|
TESTC_(RowsetA.UpdateRow(ONE_ROW, &hRow, NULL, NULL, &rgRowStatus),DB_E_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0] == DBROWSTATUS_E_DELETED);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
PROVIDER_FREE(rgPendingStatus);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(73)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Delete all rows/Undo 1/Modify 1/Update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_73()
|
|
{
|
|
const ULONG NROWS = 7;
|
|
HROW rghRow[NROWS];
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Grab all the rows in the table, starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
cModifiedRows = RowsetA.GetMaxPendingRows();
|
|
if(cModifiedRows==0 || cModifiedRows>NROWS)
|
|
cModifiedRows = NROWS;
|
|
|
|
//Delete all the rows in the table
|
|
TESTC_(RowsetA.DeleteRow(cModifiedRows,rghRow),S_OK);
|
|
|
|
//GetPendingRows, all rows should have pending changes
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED,cModifiedRows),S_OK);
|
|
|
|
//Now undo last row
|
|
TESTC_(RowsetA.UndoRow(rghRow[cModifiedRows-1]),S_OK);
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED,cModifiedRows-1), (cModifiedRows-1) ? S_OK : S_FALSE);
|
|
|
|
//Now Delete that row
|
|
TESTC_(RowsetA.DeleteRow(rghRow[cModifiedRows-1]),S_OK);
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED,cModifiedRows), S_OK);
|
|
|
|
//Call update
|
|
TESTC_(RowsetA.UpdateRow(cModifiedRows,rghRow),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TableInsert(NROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(74)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - 1 Row rowset/Delete row/Undo/Delete/Update/Undo/Update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_74()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//Create a rowset from a 1 row table
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(SELECT_ALLFROMTBL, IID_IRowset, g_p1RowTable)==S_OK);
|
|
|
|
//Grab the only row in the table, row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Delete the row in the table
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//GetPendingRows, all rows should have pending changes
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED,ONE_ROW),S_OK);
|
|
|
|
//Now undo last row
|
|
TESTC_(RowsetA.UndoRow(hRow),S_OK);
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED,NO_ROWS),S_FALSE);
|
|
|
|
//Now Delete that row
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED,ONE_ROW),S_OK);
|
|
|
|
//Call update
|
|
TESTC_(RowsetA.UpdateRow(hRow),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(75)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Insert 3 rows/Undo all/Insert 4/Modify
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_75()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(NROWS));
|
|
|
|
//Insert 3 rows into the table
|
|
TESTC_(RowsetA.InsertRow(THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Undo all of them
|
|
TESTC_(RowsetA.UndoRow(THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Insert 4 rows into the table
|
|
TESTC_(RowsetA.InsertRow(FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//Modify those rows
|
|
TESTC_(RowsetA.ModifyRow(FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//Update 2 of them
|
|
TESTC_(RowsetA.UpdateRow(rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.UpdateRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//InsertRow->SetData - is still considered a NEW Row according to the spec
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_NEW,TWO_ROWS),S_OK);
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_CHANGED, NO_ROWS),S_FALSE);
|
|
TESTC_(RowsetA.GetPendingRows(DBPENDINGSTATUS_DELETED, NO_ROWS),S_FALSE);
|
|
|
|
//Undo the other two
|
|
TESTC_(RowsetA.UndoRow(rghRow[ROW_THREE]),S_OK);
|
|
TESTC_(RowsetA.UndoRow(rghRow[ROW_FOUR]),S_OK);
|
|
TESTC_(RowsetA.GetPendingRows(NO_ROWS),S_FALSE);
|
|
|
|
//Update All, shouldn't be any updates, row 3, row 4 are invalid
|
|
TESTC_(RowsetA.UpdateRow(FOUR_ROWS,rghRow,NULL,NULL,&rgRowStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgRowStatus != NULL);
|
|
TESTC(rgRowStatus[0] == DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[1] == DBROWSTATUS_S_OK);
|
|
TESTC(rgRowStatus[2] == DBROWSTATUS_E_DELETED);
|
|
TESTC(rgRowStatus[3] == DBROWSTATUS_E_DELETED);
|
|
|
|
TESTC_(RowsetA.GetPendingRows(NO_ROWS),S_FALSE);
|
|
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgRowStatus);
|
|
RowsetA.ReleaseRows(FOUR_ROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(76)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_76()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(77)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Call Update 3 times
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_77()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = SIX_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL};
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
DBCOUNTITEM cUpdatedRows = 0;
|
|
HROW* rgUpdatedRows = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//NOTE:
|
|
//With this variation (mutliple Updates) it is important that
|
|
//we don't modify the same row twice in different updates
|
|
//Since I have bound the index column, modifiying the data will cause
|
|
//the row to be repositioned, (SQLServer) will be unable to reposition on
|
|
//that row...
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(SECOND_ROW, &rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_TWO]),S_OK);
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_THREE]),S_OK);
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_FOUR]),S_OK);
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FIVE]),S_OK);
|
|
cModifiedRows++;
|
|
|
|
//Make change(s)
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Update #1
|
|
TESTC_(RowsetA.UpdateRow(0,NULL,&cUpdatedRows,&rgUpdatedRows),S_OK);
|
|
TESTC(cUpdatedRows==cModifiedRows);
|
|
|
|
//Since 0,NULL was passed in, you can't assume the rows returned
|
|
// Are in the same order as modifed...
|
|
TESTC(FindValue(rghRow[ROW_FIVE], cUpdatedRows, rgUpdatedRows));
|
|
if(cModifiedRows >=2)
|
|
TESTC(FindValue(rghRow[ROW_TWO], cUpdatedRows, rgUpdatedRows));
|
|
if(cModifiedRows >=3)
|
|
TESTC(FindValue(rghRow[ROW_FOUR], cUpdatedRows, rgUpdatedRows));
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
|
|
//Update #2
|
|
TESTC_(RowsetA.UpdateRow(0,NULL,&cUpdatedRows,&rgUpdatedRows),S_OK);
|
|
TESTC(cUpdatedRows==NO_ROWS);
|
|
|
|
//Make a few of changes, to the previously updated rows
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_SIX]),S_OK);
|
|
cModifiedRows = 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Update #3
|
|
TESTC_(RowsetA.UpdateRow(0,NULL,&cUpdatedRows,&rgUpdatedRows),S_OK);
|
|
TESTC(cUpdatedRows==cModifiedRows);
|
|
|
|
//Since 0,NULL was passed in, you can't assume the rows returned
|
|
//Are in the same order as modifed...
|
|
TESTC(FindValue(rghRow[ROW_SIX], cUpdatedRows, rgUpdatedRows));
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC(FindValue(rghRow[ROW_ONE], cUpdatedRows, rgUpdatedRows));
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC(FindValue(rghRow[ROW_THREE], cUpdatedRows, rgUpdatedRows));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(SIX_ROWS, rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
TableInsert(TWO_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(78)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Call Update on seperate columns
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_78()
|
|
{
|
|
TBEGIN
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(79)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Update multilple rows, covering all types
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_79()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOURTEEN_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(NROWS));
|
|
|
|
//Row types
|
|
// 1. DELETEDROW (hard-deleted) g e
|
|
// 2. SOFT-DELETED g u
|
|
// 3. MODIFIED g u
|
|
// 4. MODIFIED/DELETED g u
|
|
// 5. MODIFIED/MODIFIED g u
|
|
// 6. UNDONE ROW g
|
|
// 7. BADROWHANDLE (invalid) e
|
|
// 8. INSERTED i u
|
|
// 9. INSERTED/MODIFIED i u
|
|
//10. INSERTED/MODIFIED/DELETED i u
|
|
//11. INSERTED/DELETED i u
|
|
//12. INSERTED/MODFIFIED/MODIFIED i u
|
|
//13. INSERTED/MODFIFIED/MODIFIED/DELETED i u
|
|
//14. UNCHANGED g
|
|
|
|
//g - indicates which rows require fetching/getting
|
|
//i - indicates which rows require inserting
|
|
//e - indicates which rows will produce an error
|
|
//u - indicates which rows should be reported as updated
|
|
|
|
//Obtain handle(s) of fetched rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, SIX_ROWS, rghRow),S_OK) //rows 1-6;
|
|
|
|
//Now obtain other handles
|
|
rghRow[ROW_SEVEN] = DB_NULL_HROW; //row 7
|
|
|
|
//Now obtain the inserted row handles
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_EIGHT]),S_OK) //row 8;
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_NINE]),S_OK) //row 9;
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_TEN]),S_OK) //row 10;
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_ELEVEN]),S_OK) //row 11;
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_TWELVE]),S_OK) //row 12;
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THIRTEEN]),S_OK) //row 13;
|
|
|
|
//Now modify to get the above descriptions
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_ONE]),S_OK) //hard-delete row 1;
|
|
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //soft-delete row 2;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_FOUR]),S_OK) //modify row 4;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FOUR]),S_OK) //delete row 4;
|
|
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_FIVE]),S_OK) //modify row 5;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_FIVE]),S_OK) //modify row 5;
|
|
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_SIX]),S_OK) //modify row 6;
|
|
TESTC_(RowsetA.UndoRow(rghRow[ROW_SIX]),S_OK) //undo row 6;
|
|
|
|
// row 7 is already bad
|
|
// row 8 is already inserted
|
|
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_NINE]),S_OK) //modify row 9;
|
|
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TEN]),S_OK) //modify row 10;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TEN]),S_OK) //delete row 10;
|
|
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_ELEVEN]),S_OK) //delete row 11;
|
|
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWELVE]),S_OK) //modify row 12;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWELVE]),S_OK) //modify row 12;
|
|
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THIRTEEN]),S_OK) //modify row 13;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THIRTEEN]),S_OK) //modify row 13;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THIRTEEN]),S_OK) //delete row 13;
|
|
|
|
//Now update the beast...
|
|
TESTC_(RowsetA.UpdateRow(0,NULL,&cUpdatedRows,&rgUpdatedRows),S_OK);
|
|
TESTC_(RowsetA.ReleaseRows(cUpdatedRows,rgUpdatedRows),S_OK);
|
|
|
|
//Verify array
|
|
TESTC(cUpdatedRows==SEVEN_ROWS);
|
|
|
|
//Since 0,NULL was passed in, you can't assume the rows returned
|
|
//Are in the same order as modifed...
|
|
TESTC(FindValue(rghRow[ROW_EIGHT], cUpdatedRows, rgUpdatedRows));
|
|
TESTC(FindValue(rghRow[ROW_NINE], cUpdatedRows, rgUpdatedRows));
|
|
TESTC(FindValue(rghRow[ROW_TWELVE], cUpdatedRows, rgUpdatedRows));
|
|
TESTC(FindValue(rghRow[ROW_TWO], cUpdatedRows, rgUpdatedRows));
|
|
TESTC(FindValue(rghRow[ROW_THREE], cUpdatedRows, rgUpdatedRows));
|
|
TESTC(FindValue(rghRow[ROW_FOUR], cUpdatedRows, rgUpdatedRows));
|
|
TESTC(FindValue(rghRow[ROW_FIVE], cUpdatedRows, rgUpdatedRows));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
TableInsert(SIX_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(80)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Multiple Table Update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUpdate::Variation_80()
|
|
{
|
|
TBEGIN
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCUpdate::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CRowsetUpdate::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCGetRowStatus)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCGetRowStatus - IRowsetUpdate::GetRowStatus
|
|
//| Created: 04/16/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetRowStatus::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CRowsetUpdate::Init())
|
|
// }}
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Verify GetRowStatus alters row handles RefCount correctly
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_1()
|
|
{
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS rgPendingStatus[1] = {ULONG_MAX};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//Release rows
|
|
TESTC_(RowsetA.ReleaseRows(FOUR_ROWS,rghRow),S_OK);
|
|
|
|
//GetRowStatus [invalid, 0, NULL, valid], should no nothing
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(INVALID(HCHAPTER),0,NULL,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus[0] == ULONG_MAX);
|
|
|
|
//Release again, should cause error
|
|
TESTC_(RowsetA.ReleaseRows(FOUR_ROWS,rghRow),DB_E_ERRORSOCCURRED);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [invalid, 0, NULL, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_2()
|
|
{
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS rgPendingStatus[1] = {ULONG_MAX};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//GetRowStatus [invalid, 0, NULL, NULL], do nothing
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(INVALID(HCHAPTER), 0, NULL, NULL),S_OK);
|
|
|
|
//GetRowStatus [invalid, 0, NULL, valid], should ignore rgPendingStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(INVALID(HCHAPTER), 0, NULL, rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus[0] == ULONG_MAX);
|
|
|
|
//GetRowStatus [invalid, 0, NULL, valid], should ignore rghRows and do nothing
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(INVALID(HCHAPTER), 0, rghRow, NULL), S_OK);
|
|
|
|
//GetRowStatus [invalid, 0, valid, valid], should ignore rgPendingStatus
|
|
rgPendingStatus[0] = ULONG_MAX;
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(INVALID(HCHAPTER), 0, rghRow, rgPendingStatus), S_OK);
|
|
TESTC(rgPendingStatus[0] == ULONG_MAX);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, 1, valid, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_3()
|
|
{
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL, ONE_ROW, rghRow, NULL),E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - No Changes [NULL, 1, NULL, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_4()
|
|
{
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS rgPendingStatus[1] = {ULONG_MAX};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL, ONE_ROW, NULL, rgPendingStatus),E_INVALIDARG);
|
|
TESTC(rgPendingStatus[0] == ULONG_MAX);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_5()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_6()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, 0, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_7()
|
|
{
|
|
HROW rghRow[SIX_ROWS] = {NULL,NULL,NULL,NULL,NULL,NULL};
|
|
DBROWSTATUS rgPendingStatus[1] = {ULONG_MAX};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK);
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_FOUR]),S_OK);
|
|
|
|
//Insert row(s)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_SIX]),S_OK);
|
|
if(RowsetA.AllowPendingRows(4))
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FIVE]),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,0,NULL,NULL),S_OK);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(SIX_ROWS, rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, N, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_8()
|
|
{
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[FOUR_ROWS] = {ULONG_MAX,ULONG_MAX,ULONG_MAX,ULONG_MAX};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK);
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_FOUR]),S_OK);
|
|
|
|
//Delete row(s)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_ONE]),S_OK);
|
|
|
|
//GetRowStatus (N, NULL, NULL) - E_INVALIDARG
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL, FOUR_ROWS, NULL, NULL), E_INVALIDARG);
|
|
|
|
//GetRowStatus (N, NULL, valid) - E_INVALIDARG
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL, FOUR_ROWS, NULL, rgPendingStatus), E_INVALIDARG);
|
|
TESTC(VerifyArray(FOUR_ROWS, rgPendingStatus, ULONG_MAX));
|
|
|
|
//GetRowStatus (N, valid, NULL) - E_INVALIDARG
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL, FOUR_ROWS, rghRow, NULL), E_INVALIDARG);
|
|
|
|
//GetRowStatus (N, valid, valid) - S_OK
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL, FOUR_ROWS, rghRow, rgPendingStatus), S_OK);
|
|
COMPC(rgPendingStatus[ROW_ONE], (DBPENDINGSTATUS)(RowsetA.AllowPendingRows(3) ? DBPENDINGSTATUS_DELETED : DBPENDINGSTATUS_UNCHANGED));
|
|
COMPC(rgPendingStatus[ROW_TWO], DBPENDINGSTATUS_CHANGED);
|
|
COMPC(rgPendingStatus[ROW_THREE], DBPENDINGSTATUS_UNCHANGED);
|
|
COMPC(rgPendingStatus[ROW_FOUR], (DBPENDINGSTATUS)(RowsetA.AllowPendingRows(2) ? DBPENDINGSTATUS_CHANGED : DBPENDINGSTATUS_UNCHANGED));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - N Changes [NULL, N, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_9()
|
|
{
|
|
const int NROWS = SIX_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
ULONG cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK); //modify row 2
|
|
cModifiedRows = 1;
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK); //modify row 3
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//Delete row(s)
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FIVE]),S_OK); //insert row 5
|
|
cModifiedRows++;
|
|
}
|
|
if(RowsetA.AllowPendingRows(4))
|
|
{
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_SIX]),S_OK); //insert row 6
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),DB_S_ERRORSOCCURRED);
|
|
COMPC(rgPendingStatus[0],DBPENDINGSTATUS_UNCHANGED);
|
|
COMPC(rgPendingStatus[1],DBPENDINGSTATUS_CHANGED);
|
|
COMPC(rgPendingStatus[3],DBPENDINGSTATUS_INVALIDROW);
|
|
if(cModifiedRows >=2)
|
|
COMPC(rgPendingStatus[2],DBPENDINGSTATUS_CHANGED);
|
|
if(cModifiedRows >=3)
|
|
COMPC(rgPendingStatus[4],DBPENDINGSTATUS_NEW);
|
|
if(cModifiedRows >=4)
|
|
COMPC(rgPendingStatus[5],DBPENDINGSTATUS_NEW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary - Empty Rowset [NULL, N, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_10()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate EmptyRowsetA;
|
|
TESTC_PROVIDER(EmptyRowsetA.CreateRowset(SELECT_EMPTYROWSET)==S_OK);
|
|
|
|
//Can't fetch any rows, but is useful, since we can guarentee no other
|
|
//row modidifying methods have been called...
|
|
|
|
rghRow[ROW_ONE] = DB_NULL_HROW;
|
|
rghRow[ROW_TWO] = DB_NULL_HROW;
|
|
rghRow[ROW_THREE] = INVALID(HROW);
|
|
rghRow[ROW_FOUR] = DB_NULL_HROW;
|
|
|
|
//GetRowStatus
|
|
TESTC_(EmptyRowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),DB_E_ERRORSOCCURRED);
|
|
|
|
COMPC(rgPendingStatus[0],DBPENDINGSTATUS_INVALIDROW);
|
|
COMPC(rgPendingStatus[1],DBPENDINGSTATUS_INVALIDROW);
|
|
COMPC(rgPendingStatus[2],DBPENDINGSTATUS_INVALIDROW);
|
|
COMPC(rgPendingStatus[3],DBPENDINGSTATUS_INVALIDROW);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_11()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_12()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 hard deleted 2 modified
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_13()
|
|
{
|
|
const int NROWS = FIVE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK) ;
|
|
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_TWO]),S_OK) //hard-delete row 2;
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_FOUR]),S_OK) //hard-delete row 4;
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_FIVE]),S_OK) //hard-delete row 5;
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
|
|
TESTC(rgPendingStatus[ROW_ONE] == DBPENDINGSTATUS_CHANGED);
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_INVALIDROW);
|
|
TESTC(rgPendingStatus[ROW_THREE] == (DBPENDINGSTATUS)(RowsetA.AllowPendingRows(2) ? DBPENDINGSTATUS_CHANGED : DBPENDINGSTATUS_UNCHANGED));
|
|
TESTC(rgPendingStatus[ROW_FOUR] == DBPENDINGSTATUS_INVALIDROW);
|
|
TESTC(rgPendingStatus[ROW_FIVE] == DBPENDINGSTATUS_INVALIDROW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TableInsert(THREE_ROWS); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 3 invalid
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_14()
|
|
{
|
|
const int NROWS = FIVE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,TWO_ROWS,rghRow),S_OK) ;
|
|
|
|
//Rest are invalid
|
|
rghRow[ROW_THREE] = DB_NULL_HROW;
|
|
rghRow[ROW_FOUR] = INVALID(HROW);
|
|
rghRow[ROW_FIVE] = DB_NULL_HROW;
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
|
|
TESTC(rgPendingStatus[ROW_ONE] == DBPENDINGSTATUS_CHANGED);
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_INVALIDROW);
|
|
TESTC(rgPendingStatus[ROW_FOUR] == DBPENDINGSTATUS_INVALIDROW);
|
|
TESTC(rgPendingStatus[ROW_FIVE] == DBPENDINGSTATUS_INVALIDROW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(TWO_ROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - 1 hard deleted 1 invalid 1 modified
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_15()
|
|
{
|
|
const int NROWS = FIVE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,TWO_ROWS,rghRow),S_OK) ;
|
|
|
|
//Rest are invalid
|
|
rghRow[ROW_THREE] = DB_NULL_HROW;
|
|
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_ONE]),S_OK) //delete row 1;
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_TWO]),S_OK) //modify row 2;
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
|
|
TESTC(rgPendingStatus[ROW_ONE] == DBPENDINGSTATUS_INVALIDROW);
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_CHANGED);
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_INVALIDROW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(TWO_ROWS,rghRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_16()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - All types
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_17()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = SIX_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,FOUR_ROWS,rghRow),S_OK) ;
|
|
|
|
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FIVE]),S_OK) //1 inserted;
|
|
rghRow[ROW_SIX] = DB_NULL_HROW; //1 invalid
|
|
|
|
TESTC_(RowsetA.HardDeleteRow(rghRow[ROW_THREE]),S_OK)//1 hard-deleted;
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK) //1 deleted;
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //1 modified;
|
|
|
|
//[ROW_FOUR] //1 unchanged
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
|
|
TESTC(rgPendingStatus[ROW_ONE] == (DBPENDINGSTATUS)(RowsetA.AllowPendingRows(2) ? DBPENDINGSTATUS_CHANGED : DBPENDINGSTATUS_UNCHANGED));
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_DELETED);
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_INVALIDROW);
|
|
TESTC(rgPendingStatus[ROW_FOUR] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_FIVE] == DBPENDINGSTATUS_NEW);
|
|
TESTC(rgPendingStatus[ROW_SIX] == DBPENDINGSTATUS_INVALIDROW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FIVE_ROWS,rghRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - All Unchanged
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_18()
|
|
{
|
|
const int NROWS = TWO_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,NROWS,rghRow),S_OK) ;
|
|
|
|
//Make no changes
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(VerifyArray(NROWS,rgPendingStatus,DBPENDINGSTATUS_UNCHANGED));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - All Inserted
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_19()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
cModifiedRows = RowsetA.GetMaxPendingRows();
|
|
if(cModifiedRows==0 || cModifiedRows>NROWS)
|
|
cModifiedRows = NROWS;
|
|
|
|
//Insert row handle(s)
|
|
TESTC_(RowsetA.InsertRow(cModifiedRows,rghRow),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,cModifiedRows,rghRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(VerifyArray(cModifiedRows,rgPendingStatus,DBPENDINGSTATUS_NEW));
|
|
|
|
//Update all
|
|
TESTC_(RowsetA.UpdateAll(),S_OK) ;
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - All Soft-Deleted
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_20()
|
|
{
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
DBCOUNTITEM cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK) ;
|
|
cModifiedRows = RowsetA.GetMaxPendingRows();
|
|
if(cModifiedRows==0 || cModifiedRows>NROWS)
|
|
cModifiedRows = NROWS;
|
|
|
|
//Delete row(s)
|
|
TESTC_(RowsetA.DeleteRow(cModifiedRows,rghRow),S_OK) ;
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,cModifiedRows,rghRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(VerifyArray(cModifiedRows,rgPendingStatus,DBPENDINGSTATUS_DELETED));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Insert/Modify
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_21()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
DBPENDINGSTATUS rgPendingStatus[ONE_ROW];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Insert row
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,ONE_ROW,&hRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(rgPendingStatus[ROW_ONE] == DBPENDINGSTATUS_NEW);
|
|
|
|
//An insertion followed by a modification counts as an insertion
|
|
//Update all
|
|
TESTC_(RowsetA.UpdateAll(),S_OK) ;
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Modify Delete
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_22()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
DBPENDINGSTATUS rgPendingStatus[ONE_ROW];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain handle
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
//Modify row
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
//Delete row
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,ONE_ROW,&hRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
COMPC(rgPendingStatus[ROW_ONE],DBPENDINGSTATUS_DELETED)
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Parameters - Insert/Modify/Delete
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_23()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
DBPENDINGSTATUS rgPendingStatus[ONE_ROW];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Insert row
|
|
TESTC_(RowsetA.InsertRow(&hRow),S_OK);
|
|
TESTC_(RowsetA.ModifyRow(hRow),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,ONE_ROW,&hRow,rgPendingStatus),DB_E_ERRORSOCCURRED);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(rgPendingStatus[0]==DBPENDINGSTATUS_INVALIDROW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_24()
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Insert/Delete/Modify - Update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_25()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain row handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, TWO_ROWS, rghRow),S_OK);
|
|
|
|
//Insert row
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK);
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_THREE]),S_OK);
|
|
|
|
//Update
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(rgPendingStatus[ROW_ONE] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_INVALIDROW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Make all type changes - Undo half - Update
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_26()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain row handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, TWO_ROWS, rghRow),S_OK);
|
|
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_THREE]),S_OK);
|
|
if(RowsetA.AllowPendingRows(2))
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
if(RowsetA.AllowPendingRows(3))
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//Undo
|
|
TESTC_(RowsetA.UndoRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(rgPendingStatus[ROW_ONE] == (DBPENDINGSTATUS)(RowsetA.AllowPendingRows(2) ? DBPENDINGSTATUS_CHANGED : DBPENDINGSTATUS_UNCHANGED));
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_NEW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Change N rows, GetPendingRows, GetRowStatus
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_27()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
ULONG cModifiedRows = 0;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain row handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Make N changes
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK);
|
|
cModifiedRows++;
|
|
|
|
if(RowsetA.AllowPendingRows(2))
|
|
{
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
if(RowsetA.AllowPendingRows(3))
|
|
{
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
cModifiedRows++;
|
|
}
|
|
|
|
//GetPendingRows = N
|
|
TESTC_(RowsetA.GetPendingRows(cModifiedRows),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(rgPendingStatus[ROW_ONE] == (DBPENDINGSTATUS)(RowsetA.AllowPendingRows(2) ? DBPENDINGSTATUS_CHANGED : DBPENDINGSTATUS_UNCHANGED));
|
|
TESTC(rgPendingStatus[ROW_TWO] == (DBPENDINGSTATUS)(RowsetA.AllowPendingRows(3) ? DBPENDINGSTATUS_DELETED : DBPENDINGSTATUS_UNCHANGED));
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_FOUR] == DBPENDINGSTATUS_NEW);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Call GetRowStatus 3 times
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetRowStatus::Variation_28()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[NROWS];
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
TESTC_PROVIDER(RowsetA.AllowPendingRows(NROWS));
|
|
|
|
//Make sure we have QBU turned on
|
|
if(SupportedProperty(KAGPROP_QUERYBASEDUPDATES,DBPROPSET_PROVIDERROWSET))
|
|
TESTC(RowsetA.GetProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET));
|
|
|
|
//Obtain row handles
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, THREE_ROWS, rghRow),S_OK);
|
|
|
|
//Make N changes
|
|
TESTC_(RowsetA.InsertRow(&rghRow[ROW_FOUR]),S_OK);
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK);
|
|
TESTC_(RowsetA.DeleteRow(rghRow[ROW_TWO]),S_OK);
|
|
|
|
//GetRowStatus #1
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(rgPendingStatus[ROW_ONE] == DBPENDINGSTATUS_CHANGED);
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_DELETED);
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_FOUR] == DBPENDINGSTATUS_NEW);
|
|
|
|
//GetRowStatus #2
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),S_OK);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(rgPendingStatus[ROW_ONE] == DBPENDINGSTATUS_CHANGED);
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_DELETED);
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_FOUR] == DBPENDINGSTATUS_NEW);
|
|
|
|
//Update
|
|
TESTC_(RowsetA.UpdateAll(),S_OK);
|
|
|
|
//GetRowStatus #3
|
|
TESTC_(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,NROWS,rghRow,rgPendingStatus),DB_S_ERRORSOCCURRED);
|
|
TESTC(rgPendingStatus!=NULL);
|
|
TESTC(rgPendingStatus[ROW_ONE] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_TWO] == DBPENDINGSTATUS_INVALIDROW);
|
|
TESTC(rgPendingStatus[ROW_THREE] == DBPENDINGSTATUS_UNCHANGED);
|
|
TESTC(rgPendingStatus[ROW_FOUR] == DBPENDINGSTATUS_UNCHANGED);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetRowStatus::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CRowsetUpdate::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCExtendedErrors)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCExtendedErrors - Extended Errors
|
|
//| Created: 07/25/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
|
|
BOOL TCExtendedErrors::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CRowsetUpdate::Init())
|
|
// }}
|
|
{
|
|
return TEST_PASS;
|
|
}
|
|
return TEST_FAIL;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Valid GetOriginalData calls with previous error object existing.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_1()
|
|
{
|
|
HACCESSOR hNullAccessor = DB_NULL_HACCESSOR;
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
HROW hRow = DB_NULL_HROW;
|
|
void* pData = INVALID(void*);
|
|
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get S_OK from the IRowsetUpdate method.
|
|
//We then check extended errors to verify nothing is set since an
|
|
//error object shouldn't exist following a successful call.
|
|
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Create a NULL Accessor
|
|
TESTC_(RowsetA.pIAccessor()->CreateAccessor(DBACCESSOR_ROWDATA,0,NULL,0,&hNullAccessor,NULL),S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,hNullAccessor,pData)),S_OK);
|
|
|
|
//Do extended check following GetOriginalData
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
TESTC(pData==INVALID(void*));
|
|
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(hNullAccessor ,NULL),S_OK);
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(hAccessor ,NULL),DB_E_BADACCESSORHANDLE);
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(INVALID(HACCESSOR),NULL),DB_E_BADACCESSORHANDLE);
|
|
TESTC_(RowsetA.pIAccessor()->ReleaseAccessor(DB_NULL_HACCESSOR ,NULL),DB_E_BADACCESSORHANDLE);
|
|
|
|
CLEANUP:
|
|
//Release the Accesssor
|
|
RowsetA.ReleaseAccessor(hNullAccessor);
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
|
|
//Release the row handle
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid GetOriginalData calls with previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_2()
|
|
{
|
|
//HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
HROW hRow = DB_NULL_HROW;
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
//The work arround is to create a new rowset in this variation, which
|
|
//will guarentee we don't have to call restart poisiton.
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Get the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
//Call GetOriginalData with NULL pDdata
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,NULL)),E_INVALIDARG);
|
|
|
|
//Do extended check following GetOriginalData
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid GetOriginalData calls with no previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_3()
|
|
{
|
|
//HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
HROW hRow = DB_NULL_HROW;
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, with no error object on
|
|
//the current thread, try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
//The work arround is to create a new rowset in this variation, which
|
|
//will guarentee we don't have to call restart poisiton.
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Get the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Call GetOriginalData with NULL pDdata
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,RowsetA.m_hAccessor,NULL)),E_INVALIDARG);
|
|
|
|
//Do extended check following GetOriginalData
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Valid GetPendingRows calls with previous error object existing.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_4()
|
|
{
|
|
TBEGIN
|
|
const int NROWS = THREE_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL};
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get S_OK from the IRowsetUpdate method.
|
|
//We then check extended errors to verify nothing is set since an
|
|
//error object shouldn't exist following a successful call.
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&rghRow[ROW_ONE]),S_OK) ;
|
|
TESTC_(RowsetA.GetNextRows(&rghRow[ROW_TWO]),S_OK) ;
|
|
|
|
//Make 3 changes
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL)),S_OK);
|
|
|
|
//Do extended check following GetPendingRows
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid GetPendingRows calls with previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_5()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_INVALIDROW
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_INVALIDROW,&cPendingRows,&rgPendingRows,&rgPendingStatus)),E_INVALIDARG);
|
|
|
|
//Do extended check following GetPendingRows
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid GetPendingRows calls with no previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_6()
|
|
{
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
DBCOUNTITEM cPendingRows;
|
|
HROW* rgPendingRows = NULL;
|
|
DBPENDINGSTATUS* rgPendingStatus = NULL;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, with no error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the row handle(s)
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS, rghRow),S_OK);
|
|
|
|
//Modify row(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_THREE]),S_OK) //modify row 3;
|
|
|
|
//GetPendingRows DBPENDINGSTATUS_INVALIDROW
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_INVALIDROW,&cPendingRows,&rgPendingRows,&rgPendingStatus)),E_INVALIDARG);
|
|
|
|
//Do extended check following GetPendingRows
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
COMPC(cPendingRows,NO_ROWS)
|
|
TESTC(rgPendingRows==NULL && rgPendingStatus==NULL);
|
|
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS, rghRow);
|
|
PROVIDER_FREE(rgPendingRows)
|
|
PROVIDER_FREE(rgPendingStatus)
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Valid GetRowStatus calls with previous error object existing.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_7()
|
|
{
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
DBPENDINGSTATUS rgPendingStatus[1] = {ULONG_MAX};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get S_OK from the IRowsetUpdate method.
|
|
//We then check extended errors to verify nothing is set since an
|
|
//error object shouldn't exist following a successful call.
|
|
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
//GetRowStatus [invalid, 0, NULL, valid], should no nothing
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetRowStatus(INVALID(HCHAPTER),0,NULL,rgPendingStatus)),S_OK);
|
|
|
|
//Do extended check following GetRowStatus
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
TESTC(rgPendingStatus[0] == ULONG_MAX);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid GetRowStatus calls with previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_8()
|
|
{
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
//GetRowStatus
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,ONE_ROW,rghRow,NULL)),E_INVALIDARG);
|
|
|
|
//Do extended check following GetRowStatus
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid GetRowStatus calls with no previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_9()
|
|
{
|
|
HROW rghRow[FOUR_ROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, with no error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Fetch rows
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, FOUR_ROWS, rghRow),S_OK);
|
|
|
|
//GetRowStatus
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->GetRowStatus(NULL,ONE_ROW,rghRow,NULL)),E_INVALIDARG);
|
|
|
|
//Do extended check following GetRowStatus
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(FOUR_ROWS, rghRow);
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Valid Undo calls with previous error object existing.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_10()
|
|
{
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get S_OK from the IRowsetUpdate method.
|
|
//We then check extended errors to verify nothing is set since an
|
|
//error object shouldn't exist following a successful call.
|
|
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->Undo(NULL,0,NULL,NULL,NULL,NULL)),S_OK);
|
|
|
|
//Do extended check following Undo
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid Undo calls with previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_11()
|
|
{
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
HROW* rgRowsUndone;
|
|
DBROWSTATUS* rgRowStatus;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->Undo(INVALID(HCHAPTER),ONE_ROW,NULL,&cRowsUndone,&rgRowsUndone,&rgRowStatus)),E_INVALIDARG);
|
|
|
|
//Do extended check following Undo
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
COMPC(cRowsUndone,NO_ROWS)
|
|
TESTC(rgRowsUndone==NULL && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid Undo calls with no previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_12()
|
|
{
|
|
DBCOUNTITEM cRowsUndone = 1;
|
|
HROW* rgRowsUndone;
|
|
DBROWSTATUS* rgRowStatus;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, with no error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->Undo(INVALID(HCHAPTER),ONE_ROW,NULL,&cRowsUndone,&rgRowsUndone,&rgRowStatus)),E_INVALIDARG);
|
|
|
|
//Do extended check following Undo
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
COMPC(cRowsUndone,NO_ROWS)
|
|
TESTC(rgRowsUndone==NULL && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Valid Update calls with previous error object existing.
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_13()
|
|
{
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get S_OK from the IRowsetUpdate method.
|
|
//We then check extended errors to verify nothing is set since an
|
|
//error object shouldn't exist following a successful call.
|
|
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->Update(NULL,0,NULL,NULL,NULL,NULL)),S_OK);
|
|
|
|
//Do extended check following Update
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid Update calls with previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_14()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
//For each method of the interface, first create an error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS,rghRow),S_OK);
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
//create an error object
|
|
TESTC(m_pExtError->CauseError());
|
|
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->Update(INVALID(HCHAPTER),NROWS,NULL,&cUpdatedRows,&rgUpdatedRows,&rgRowStatus)),E_INVALIDARG);
|
|
|
|
//Do extended check following Update
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
TESTC(cUpdatedRows==0 && rgUpdatedRows==NULL && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Invalid Update calls with no previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_15()
|
|
{
|
|
TBEGIN
|
|
DBCOUNTITEM cUpdatedRows = 1;
|
|
HROW* rgUpdatedRows = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
|
|
const int NROWS = FOUR_ROWS;
|
|
HROW rghRow[NROWS] = {NULL,NULL,NULL,NULL};
|
|
|
|
//For each method of the interface, with no error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(DBPROP_CANHOLDROWS)==S_OK);
|
|
|
|
//Obtain handle(s), starting at row 1
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, NROWS,rghRow),S_OK);
|
|
//Make changes(s)
|
|
TESTC_(RowsetA.ModifyRow(rghRow[ROW_ONE]),S_OK) //modify row 1;
|
|
|
|
TESTC_(m_hr=(RowsetA.pIRowsetUpdate()->Update(INVALID(HCHAPTER),NROWS,NULL,&cUpdatedRows,&rgUpdatedRows,&rgRowStatus)),E_INVALIDARG);
|
|
|
|
//Do extended check following Update
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
|
|
TESTC(cUpdatedRows==0 && rgUpdatedRows==NULL && rgRowStatus==NULL);
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(NROWS,rghRow);
|
|
PROVIDER_FREE(rgUpdatedRows);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc S_FALSE GetPendingRows call with no previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_16()
|
|
{
|
|
DBCOUNTITEM cPendingRows = 1;
|
|
|
|
CRowsetUpdate RowsetA;
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//For each method of the interface, with no error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
TESTC_(m_hr=RowsetA.pIRowsetUpdate()->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,NULL,NULL),S_FALSE);
|
|
//Do extended check following Update
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
COMPC(cPendingRows,NO_ROWS);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
//}}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DB_E_DELETEDROW GetOriginalData call with no previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_17()
|
|
{
|
|
HROW hRow = DB_NULL_HROW;
|
|
CRowsetUpdate RowsetA;
|
|
|
|
//For each method of the interface, with no error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
RowsetA.SetSettableProperty(KAGPROP_QUERYBASEDUPDATES, DBPROPSET_PROVIDERROWSET);
|
|
TESTC_PROVIDER(RowsetA.CreateRowset()==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Hard-delete the row
|
|
TESTC_(RowsetA.HardDeleteRow(hRow),S_OK);
|
|
|
|
//Call GetOriginalData on the hard deleted row
|
|
TESTC_(m_hr=RowsetA.GetOriginalData(hRow, &RowsetA.m_pData),DB_E_DELETEDROW);
|
|
|
|
//Do extended check following Update
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
TESTC(RowsetA.m_pData!=NULL) //provider shouldn't touch my alloced buffer;
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseRows(hRow);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
//}}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DB_E_BADACCESSORTYPE GetOriginal call with no previous error object existing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCExtendedErrors::Variation_18()
|
|
{
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
HROW hRow = DB_NULL_HROW;
|
|
HRESULT hr = S_OK;
|
|
|
|
//For each method of the interface, with no error object on
|
|
//the current thread, then try get a failure from the IRowsetUpdate method.
|
|
//We then check extended errors to verify the right extended error behavior.
|
|
|
|
//Create the rowset
|
|
CRowsetUpdate RowsetA;
|
|
RowsetA.SetSettableProperty(DBPROP_OTHERUPDATEDELETE);
|
|
TESTC_PROVIDER(RowsetA.CreateCommand()==S_OK);
|
|
|
|
//Create an invalid Accessor for use with GetOriginalData
|
|
//Must be done on the CommandObject, ParameterAccessors are not allowed
|
|
//to be created on the RowsetObject
|
|
TEST2C_(hr = GetAccessorAndBindings(RowsetA.pICommand(),DBACCESSOR_PARAMETERDATA,&hAccessor,
|
|
NULL,NULL,NULL,DBPART_ALL,UPDATEABLE_COLS_BOUND,FORWARD,
|
|
NO_COLS_BY_REF,NULL,NULL,NULL,DBTYPE_BYREF,0,NULL,NULL,
|
|
NO_COLS_OWNED_BY_PROV, DBPARAMIO_INPUT), S_OK, DB_E_BADACCESSORFLAGS);
|
|
|
|
if(hr == S_OK)
|
|
{
|
|
//Now that we have the Accessor Created, now create the rowset
|
|
//Must be a command query, since the accessor was created on the command
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(SELECT_REVCOLLIST)==S_OK);
|
|
|
|
//Obtain the first row
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW, &hRow),S_OK);
|
|
|
|
//Call GetOriginalData with an invalid accessor type
|
|
TESTC_(m_hr=RowsetA.pIRowsetUpdate()->GetOriginalData(hRow,hAccessor,RowsetA.m_pData),DB_E_BADACCESSORTYPE);
|
|
//Do extended check following Update
|
|
TESTC(m_pExtError->ValidateExtended(m_hr, RowsetA.pIRowsetUpdate(), IID_IRowsetUpdate, LONGSTRING(__FILE__), __LINE__));
|
|
TESTC(RowsetA.m_pData!=NULL);
|
|
}
|
|
else
|
|
{
|
|
//Make sure the provider doesn't support parameters (validated immediately)
|
|
TESTC_(QI(RowsetA.pICommand(), IID_ICommandWithParameters), E_NOINTERFACE);
|
|
}
|
|
|
|
CLEANUP:
|
|
RowsetA.ReleaseAccessor(hAccessor);
|
|
RowsetA.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
//}}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCExtendedErrors::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CRowsetUpdate::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCZombie)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCZombie - Zombie testing of IRowsetUpdate
|
|
//| Created: 07/22/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCZombie::Init()
|
|
{
|
|
TBEGIN
|
|
m_cPropSets = 0;
|
|
m_rgPropSets = NULL;
|
|
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CTransaction::Init())
|
|
// }}
|
|
{
|
|
//Set Properties
|
|
SetProperty(DBPROP_UPDATABILITY, DBPROPSET_ROWSET, &m_cPropSets, &m_rgPropSets, (void*)DBPROPVAL_UP_ALL,DBTYPE_I4);
|
|
|
|
//register interface to be tested
|
|
if(RegisterInterface(ROWSET_INTERFACE,IID_IRowsetUpdate))
|
|
return TRUE;
|
|
}
|
|
|
|
//Not all providers have to support transactions
|
|
//If a required interface, an error would have been posted by VerifyInterface
|
|
TEST_PROVIDER(m_pITransactionLocal != NULL);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Zombie - ABORT with fRetaining == TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_1()
|
|
{
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
CRowsetUpdate RowsetA;
|
|
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS rgRowStatus[ONE_ROW];
|
|
HRESULT ExpectedHr = E_UNEXPECTED;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IOpenRowset interface
|
|
TESTC_PROVIDER(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIRowsetUpdate,m_cPropSets,m_rgPropSets));
|
|
TESTC(pIRowsetUpdate!=NULL);
|
|
TESTC(m_pIRowset!=NULL) //Rowset interface from CTransAction;
|
|
|
|
//Obtain the first row
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(m_pIRowset)==S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make a change, (delete it)
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//Abort the Transaction with fRetaining==TRUE
|
|
TESTC(GetAbort(TRUE));
|
|
|
|
//Obtain the ABORTPRESERVE flag and adjust ExpectedHr
|
|
if(m_fAbortPreserve)
|
|
ExpectedHr = S_OK;
|
|
|
|
//Verify we still can use GetOriginalData after an ABORT
|
|
TESTC_(pIRowsetUpdate->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),ExpectedHr);
|
|
|
|
//Verify we still can use GetRowStatus after an ABORT
|
|
TESTC_(pIRowsetUpdate->GetRowStatus(NULL,ONE_ROW,&hRow,rgRowStatus),ExpectedHr);
|
|
|
|
//Verify we still can use GetPendingRows after an ABORT
|
|
TESTC_(pIRowsetUpdate->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
//Verify we still can use Update (all) after an ABORT
|
|
TESTC_(pIRowsetUpdate->Update(NULL,0,NULL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
//Verify we still can use Undo (all) after an ABORT
|
|
TESTC_(pIRowsetUpdate->Undo(NULL,0,NULL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
RowsetA.ReleaseRows(hRow);
|
|
CleanUpTransaction(S_OK);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Zombie - ABORT with fRetaining == FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_2()
|
|
{
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
CRowsetUpdate RowsetA;
|
|
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS rgRowStatus[ONE_ROW];
|
|
HRESULT ExpectedHr = E_UNEXPECTED;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IOpenRowset interface
|
|
TESTC_PROVIDER(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIRowsetUpdate,m_cPropSets,m_rgPropSets));
|
|
TESTC(pIRowsetUpdate!=NULL);
|
|
TESTC(m_pIRowset!=NULL) //Rowset interface from CTransAction;
|
|
|
|
//Obtain the first row
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(m_pIRowset)==S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make a change, (delete it)
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//Abort the Transaction with fRetaining==FALSE
|
|
TESTC(GetAbort(FALSE));
|
|
|
|
//Obtain the ABORTPRESERVE flag and adjust ExpectedHr
|
|
if(m_fAbortPreserve)
|
|
ExpectedHr = S_OK;
|
|
|
|
//Verify we still can use GetOriginalData after an ABORT
|
|
TESTC_(pIRowsetUpdate->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),ExpectedHr);
|
|
|
|
//Verify we still can use GetRowStatus after an ABORT
|
|
TESTC_(pIRowsetUpdate->GetRowStatus(NULL,ONE_ROW,&hRow,rgRowStatus),ExpectedHr);
|
|
|
|
//Verify we still can use GetPendingRows after an ABORT
|
|
TESTC_(pIRowsetUpdate->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
//Verify we still can use Update (all) after an ABORT
|
|
TESTC_(pIRowsetUpdate->Update(NULL,0,NULL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
//Verify we still can use Undo (all) after an ABORT
|
|
TESTC_(pIRowsetUpdate->Undo(NULL,0,NULL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
RowsetA.ReleaseRows(hRow);
|
|
CleanUpTransaction(XACT_E_NOTRANSACTION); //No longer in a transaction
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Zombie - COMMIT with fRetaining == TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_3()
|
|
{
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
CRowsetUpdate RowsetA;
|
|
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS rgRowStatus[ONE_ROW];
|
|
HRESULT ExpectedHr = E_UNEXPECTED;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IOpenRowset interface
|
|
TESTC_PROVIDER(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIRowsetUpdate,m_cPropSets,m_rgPropSets));
|
|
TESTC(pIRowsetUpdate!=NULL);
|
|
TESTC(m_pIRowset!=NULL) //Rowset interface from CTransAction;
|
|
|
|
//Obtain the first row
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(m_pIRowset)==S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make a change, (delete it)
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//Commit the Transaction with fRetaining==TRUE
|
|
TESTC(GetCommit(TRUE));
|
|
|
|
//Obtain the COMMITPRESERVE flag and adjust ExpectedHr
|
|
if(m_fCommitPreserve)
|
|
ExpectedHr = S_OK;
|
|
|
|
//Verify we still can use GetOriginalData after an COMMIT
|
|
TESTC_(pIRowsetUpdate->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),ExpectedHr);
|
|
|
|
//Verify we still can use GetRowStatus after an COMMIT
|
|
TESTC_(pIRowsetUpdate->GetRowStatus(NULL,ONE_ROW,&hRow,rgRowStatus),ExpectedHr);
|
|
|
|
//Verify we still can use GetPendingRows after an COMMIT
|
|
TESTC_(pIRowsetUpdate->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
//Verify we still can use Update (all) after an COMMIT
|
|
TESTC_(pIRowsetUpdate->Update(NULL,0,NULL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
//Verify we still can use Undo (all) after an COMMIT
|
|
TESTC_(pIRowsetUpdate->Undo(NULL,0,NULL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
RowsetA.ReleaseRows(hRow);
|
|
CleanUpTransaction(S_OK);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Zombie - COMMIT with fRetaining == TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_4()
|
|
{
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
CRowsetUpdate RowsetA;
|
|
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS rgRowStatus[ONE_ROW];
|
|
HRESULT ExpectedHr = E_UNEXPECTED;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IOpenRowset interface
|
|
TESTC_PROVIDER(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIRowsetUpdate,m_cPropSets,m_rgPropSets));
|
|
TESTC(pIRowsetUpdate!=NULL);
|
|
TESTC(m_pIRowset!=NULL) //Rowset interface from CTransAction;
|
|
|
|
//Obtain the first row
|
|
TESTC_PROVIDER(RowsetA.CreateRowset(m_pIRowset)==S_OK);
|
|
TESTC_(RowsetA.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make a change, (delete it)
|
|
TESTC_(RowsetA.DeleteRow(hRow),S_OK);
|
|
|
|
//Commit the Transaction with fRetaining==FALSE
|
|
TESTC(GetCommit(FALSE));
|
|
|
|
//Obtain the COMMITPRESERVE flag and adjust ExpectedHr
|
|
if(m_fCommitPreserve)
|
|
ExpectedHr = S_OK;
|
|
|
|
//Verify we still can use GetOriginalData after an COMMIT
|
|
TESTC_(pIRowsetUpdate->GetOriginalData(hRow,RowsetA.m_hAccessor,RowsetA.m_pData),ExpectedHr);
|
|
|
|
//Verify we still can use GetRowStatus after an COMMIT
|
|
TESTC_(pIRowsetUpdate->GetRowStatus(NULL,ONE_ROW,&hRow,rgRowStatus),ExpectedHr);
|
|
|
|
//Verify we still can use GetPendingRows after an COMMIT
|
|
TESTC_(pIRowsetUpdate->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
//Verify we still can use Update (all) after an COMMIT
|
|
TESTC_(pIRowsetUpdate->Update(NULL,0,NULL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
//Verify we still can use Undo (all) after an COMMIT
|
|
TESTC_(pIRowsetUpdate->Undo(NULL,0,NULL,NULL,NULL,NULL),ExpectedHr);
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
RowsetA.ReleaseRows(hRow);
|
|
CleanUpTransaction(XACT_E_NOTRANSACTION); //No longer in a transaction
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCZombie::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTransaction::Terminate());
|
|
//FreeProperties
|
|
FreeProperties(&m_cPropSets,&m_rgPropSets);
|
|
return(CTransaction::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|