415 lines
17 KiB
C++
415 lines
17 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright 1995-2000 Microsoft Corporation.
|
|
//
|
|
// @doc
|
|
//
|
|
// @module TXNBASE.HPP | Base classes for transacted rowsets.
|
|
//
|
|
// @rev 01 | 02-04-96 | Microsoft | Created
|
|
// @rev 02 | 12-01-96 | Microsoft | Updated
|
|
//
|
|
|
|
#include "oledb.h" // OLE DB Header Files
|
|
#include "oledberr.h"
|
|
#include "transact.h"
|
|
|
|
#include "privlib.h" //Include private library, which includes
|
|
#include "msdasql.h" //Kagera specific header file
|
|
|
|
//--------------------------------------------------------------------
|
|
//Externs Defined in TxnBase.cpp
|
|
//--------------------------------------------------------------------
|
|
extern ULONG g_ulLastActualDelete;
|
|
extern ULONG g_ulLastActualInsert;
|
|
extern ULONG g_ulFirstRowInTable;
|
|
|
|
extern void g_DeleteAndInsertIncrement();
|
|
extern void g_InsertIncrement();
|
|
extern void g_DeleteIncrement();
|
|
|
|
enum EASYNC
|
|
{
|
|
EASYNCTRUE,
|
|
EASYNCFALSE,
|
|
EASYNCNOTSUPPORTED
|
|
};
|
|
|
|
enum ePrptIdx
|
|
{
|
|
IDX_CommitPreserve=0,
|
|
IDX_AbortPreserve,
|
|
IDX_OtherUpdateDelete,
|
|
IDX_OtherInsert,
|
|
IDX_CommandTimeout,
|
|
IDX_IRowsetUpdate,
|
|
IDX_IRowsetChange
|
|
};
|
|
|
|
const ULONG g_PROPERTY_COUNT = IDX_IRowsetChange+1;
|
|
|
|
typedef struct tagDBPrptRecord
|
|
{
|
|
DBPROPID dwPropID;
|
|
BOOL fSupported;
|
|
VARIANT_BOOL fDefault;
|
|
DBPROPFLAGS dwFlags;
|
|
BOOL fProviderSupported;
|
|
}DBPrptRecord;
|
|
|
|
extern DBPrptRecord g_rgDBPrpt[g_PROPERTY_COUNT];
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Defines
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
//Use a value not valid for DBPROP_SUPPORTEDTXNDDL to represent that it is not a supported property
|
|
#define NOT_SUPPORTED DBPROPVAL_TC_NONE | DBPROPVAL_TC_DML | DBPROPVAL_TC_DDL_COMMIT | DBPROPVAL_TC_DDL_IGNORE | DBPROPVAL_TC_ALL
|
|
|
|
//Number of milliseconds need to wait before Jet refreshes to recognize changes
|
|
//There is supposedly only a 2 second lag time in Jet, but wait 5 seconds just to be sure
|
|
#define SLEEP_TIME 7000
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Base Class Declarations
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
//--------------------------------------------------------------------
|
|
// @class CTxnRowset | Transactable rowset to be encapsulated by CTxn
|
|
// @base public | CRowsetObject
|
|
//--------------------------------------------------------------------
|
|
class CTxnRowset : public CRowsetObject
|
|
{
|
|
// @access public
|
|
public:
|
|
|
|
//@cmember Transaction Local interface for this session
|
|
ITransactionLocal *m_pITxnLocal;
|
|
//#ifdef TXNJOIN
|
|
//@cmember Transaction Join interface for this session
|
|
ITransactionJoin *m_pITxnJoin;
|
|
//#endif//TXNJOIN
|
|
//@cmember Transaction Join interface for this session
|
|
CTable *m_pCTable;
|
|
//@cmember Count of bindings for GetData
|
|
DBCOUNTITEM m_cReadBindings;
|
|
//@cmember Array of bindings for GetData
|
|
DBBINDING *m_rgReadBindings;
|
|
//@cmember Accessor for GetData
|
|
HACCESSOR m_hReadAccessor;
|
|
//@cmember Row size for GetData
|
|
DBLENGTH m_cbReadRowSize;
|
|
//@cmember Flag indicating whether rowset is preserved on abort
|
|
BOOL m_fAbortPreserve;
|
|
//@cmember Flag indicating whether rowset is preserved on commit
|
|
BOOL m_fCommitPreserve;
|
|
//@cmember Flag indicating what DDL is supported in TXNS
|
|
DWORD m_fDDLBehavior;
|
|
|
|
//NOTE: We use enums for these values so we can have a NOT SUPPORTED
|
|
//value (in addition to valid BOOL values) which we check
|
|
//in individual test cases later on.
|
|
|
|
//@cmember Flag indicating whether async commit is supported
|
|
EASYNC m_eAsyncCommit;
|
|
//@cmember Flag indicating Async Abort support
|
|
EASYNC m_eAsyncAbort;
|
|
|
|
//@cmember CTOR
|
|
CTxnRowset(LPWSTR tcName);
|
|
//@cmember Initialization
|
|
virtual BOOL Init();
|
|
//@cmember Termination
|
|
virtual BOOL Terminate();
|
|
|
|
//@cmember Sets the session's autocommit isolation level
|
|
HRESULT SetAutoCommitIsoLevel(ULONG IsoLevel);
|
|
|
|
//@cmember Function to create the rowset and release any property error memory
|
|
virtual HRESULT MakeRowset();
|
|
//@cmember Function to create the rowset and release any property error memory
|
|
virtual HRESULT MakeRowsetReadOnly();
|
|
//@cmember Pure virtual function to set the properties to
|
|
//generate the correct rowset on CreateRowsetObject
|
|
virtual BOOL SetTxnRowsetProperties() = 0;
|
|
|
|
//@cmember Finds a row and optionally returns the hRow for that row
|
|
BOOL FindRow(ULONG ulRowNum, HROW * hRow);
|
|
//@cmember Commits current txn, fNewUnitOfWork sets whether
|
|
//a new transaction is started, or we revert to autocommit mode.
|
|
//fPreserveRowset sets whether or not the rowset is kept after the commit.
|
|
virtual HRESULT Commit(BOOL fPreserveRowset = FALSE, BOOL fNewUnitOfWork = FALSE);
|
|
//@cmember Aborts current txn, fNewUnitOfWork sets whether
|
|
//a new transaction is started, or we revert to autocommit mode.
|
|
//fPreserveRowset sets whether or not the rowset is kept after the abort.
|
|
virtual HRESULT Abort(BOOL fPreserveRowset = FALSE, BOOL fNewUnitOfWork = FALSE);
|
|
//@cmember Commits current txn, fNewUnitOfWork sets whether
|
|
//a new transaction is started, or we revert to autocommit mode.
|
|
//fPreserveRowset sets whether or not the rowset is kept after the commit.
|
|
//#ifdef TXNJOIN
|
|
virtual HRESULT CommitCoord(BOOL fNewUnitOfWork = FALSE, ITransaction *pITransaction = NULL,ITransactionJoin *pITransactionJoin=NULL);
|
|
//@cmember Aborts current txn, fNewUnitOfWork sets whether
|
|
//a new transaction is started, or we revert to autocommit mode.
|
|
//fPreserveRowset sets whether or not the rowset is kept after the abort.
|
|
virtual HRESULT AbortCoord(BOOL fNewUnitOfWork = FALSE, ITransaction *pITransaction = NULL,ITransactionJoin *pITransactionJoin=NULL);
|
|
//@cmember Dummy necessary virtual function needed to
|
|
//instantiate since we inherit from CTestCases
|
|
//#endif//TXNJOIN
|
|
inline void *GetVarInfo(const long){return (void *)NULL; }
|
|
//@cmember Dummy necessary virtual function needed to
|
|
//instantiate since we inherit from CTestCases
|
|
inline const WCHAR *GetCaseDesc(void){return (const WCHAR *)NULL; }
|
|
|
|
};
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @class CTxnRORowset | Transactable Read Only rowset
|
|
// @base public | CTxnRowset
|
|
//--------------------------------------------------------------------
|
|
class CTxnRORowset : public CTxnRowset
|
|
{
|
|
// @access public
|
|
public:
|
|
//@cmember CTOR
|
|
CTxnRORowset(LPWSTR tcName) : CTxnRowset(tcName){};
|
|
//@cmember Initialization - Creates a read only rowset
|
|
virtual BOOL Init();
|
|
//@cmember Cleans up read only rowset
|
|
virtual BOOL Terminate();
|
|
//@cmember Sets the properties to generate the correct rowset on CreateRowsetObject
|
|
virtual BOOL SetTxnRowsetProperties();
|
|
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
// @class CTxnChgRowset | Transactable updateable rowset
|
|
// @base public | CTxnRowset
|
|
//--------------------------------------------------------------------
|
|
class CTxnChgRowset : public CTxnRowset
|
|
{
|
|
|
|
// @access public
|
|
public:
|
|
//@cmember Whether or not to bind long data. By default false
|
|
BLOBTYPE m_fBindLongData;
|
|
//@cmember Whether or not this provider supports IRowsetChange
|
|
BOOL m_fChange;
|
|
//@cmember Whether or not this provider supports IRowsetUpdate
|
|
BOOL m_fUpdate;
|
|
//@cmember Count of updateable columns, to be used for NewRow and Change
|
|
DBORDINAL m_cUpdateableCols;
|
|
//@cmember Array of updateable columns, to be used for NewRow and Change
|
|
DBORDINAL *m_rgUpdateableCols;
|
|
//@cmember Count of bindings for NewRow and Change
|
|
DBORDINAL m_cUpdateBindings;
|
|
//@cmember Array of bindings for NewRow and Change
|
|
DBBINDING *m_rgUpdateBindings;
|
|
//@cmember Accessor for NewRow and Change
|
|
HACCESSOR m_hUpdateAccessor;
|
|
//@cmember Row size for NewRow and Change
|
|
DBLENGTH m_cbUpdateRowSize;
|
|
//@cmember Flag checked at commit time, to determine if an insert
|
|
//has been committed.
|
|
BOOL m_fTxnPendingInsert;
|
|
//@cmember Flag checked at commit time, to determine if a delete
|
|
//has been committed.
|
|
BOOL m_fTxnPendingDelete;
|
|
//@cmember Flag checked at commit time, to determine if a change
|
|
//has been committed.
|
|
BOOL m_fTxnPendingChange;
|
|
//@cmember Whether or not a transaction is started on this DB Session
|
|
BOOL m_fTxnStarted;
|
|
|
|
//@cmember CTOR
|
|
CTxnChgRowset(LPWSTR tcName);
|
|
//@cmember Initialization - Creates an updateable rowset
|
|
virtual BOOL Init();
|
|
//Copies pertainent info when two rowsets are sharing the same
|
|
//session and txn, and the give rowset has made a change
|
|
void CopyTxnInfo(CTxnChgRowset * pTxnChgRowset);
|
|
//@cmember Sets the properties to generate the correct rowset on CreateRowsetObject
|
|
virtual BOOL SetTxnRowsetProperties();
|
|
//@cmember Termination - Cleans up all non base rowset interfaces
|
|
virtual BOOL Terminate();
|
|
//@cmember Commits current txn, fNewUnitOfWork sets whether
|
|
//a new transaction is started, or we revert to autocommit mode.
|
|
//fPreserveRowset sets whether or not the rowset is kept after the commit.
|
|
virtual HRESULT Commit(BOOL fPreserveRowset = FALSE, BOOL fNewUnitOfWork = FALSE);
|
|
//@cmember Starts a txn, setting the m_fTxnStarted flag
|
|
virtual HRESULT StartTxn(ISOLEVEL isoLevel);
|
|
//#ifdef TXNJOIN
|
|
//@cmember Commits current txn, fNewUnitOfWork sets whether
|
|
//a new transaction is started, or we revert to autocommit mode.
|
|
//fPreserveRowset sets whether or not the rowset is kept after the commit.
|
|
virtual HRESULT CommitCoord(BOOL fNewUnitOfWork = FALSE, ITransaction *pITransaction = NULL,ITransactionJoin *pITransactionJoin=NULL);
|
|
//@cmember Gets a TransactionJoin interface pointer from a session object
|
|
virtual HRESULT GetTxnJoin();
|
|
//@cmember Gets a TransactionJoin interface pointer from a session object
|
|
virtual BOOL StartCoordTxn(ITransaction **ppITransaction,ISOLEVEL isolevel);
|
|
//@cmember Aborts the coordinated transacrtion and frees the pointer to TxnJoin
|
|
virtual BOOL FreeJoinTxn();
|
|
//@cmember Frees the ITrans interface and cloese connectin to dtc
|
|
virtual BOOL FreeCoordTxn(ITransaction *pITransaction);
|
|
//#endif//TXNJOIN
|
|
//@cmember Aborts current txn, fNewUnitOfWork sets whether
|
|
//a new transaction is started, or we revert to autocommit mode.
|
|
//fPreserveRowset sets whether or not the rowset is kept after the abort.
|
|
virtual HRESULT Abort(BOOL fPreserveRowset = FALSE, BOOL fNewUnitOfWork = FALSE);
|
|
//#ifdef TXNJOIN
|
|
//@cmember Aborts current txn, fNewUnitOfWork sets whether
|
|
//a new transaction is started, or we revert to autocommit mode.
|
|
//fPreserveRowset sets whether or not the rowset is kept after the abort.
|
|
virtual HRESULT AbortCoord(BOOL fNewUnitOfWork = FALSE, ITransaction *pITransaction = NULL,ITransactionJoin *pITransactionJoin=NULL);
|
|
//#endif//TXNJOIN
|
|
//@cmember Inserts a row given the row number -- does not explicitly commit
|
|
BOOL Insert( ULONG ulRowNum,
|
|
HROW *phNewRow = NULL,
|
|
BOOL fDEFAULT = FALSE);
|
|
//@cmember Deletes a row given the row number -- does not explicitly commit
|
|
BOOL Delete(ULONG ulRowNum, HROW * phRow = NULL);
|
|
//@cmember Deletes and Inserts (ie, Changes a row) given
|
|
//the row numbers -- does not explicitly commit
|
|
BOOL Change( ULONG ulDeleteRowNum,
|
|
ULONG ulInsertRowNum,
|
|
HROW *phRow = NULL,
|
|
BOOL fIGNORE = FALSE,
|
|
BOOL fDEFAULT = FALSE);
|
|
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
// @class CTxn | Base Class for Transaction testing.
|
|
// @base public | CDataSourceObject
|
|
//--------------------------------------------------------------------
|
|
class CTxn : public CSessionObject
|
|
{
|
|
|
|
// @access public
|
|
public:
|
|
//@cmember Row Number which is currently being inserted. This row
|
|
//may or may not be committed yet, so it may not be visible to other txns.
|
|
ULONG m_ulCurrentInsertRow;
|
|
//@cmember Row Number which is currently being deleted. This row
|
|
//may or may not be committed yet, so it may not be visible to other txns.
|
|
ULONG m_ulCurrentDeleteRow;
|
|
//@cmember New Row Number of row which is currently being changed. This change
|
|
//may or may not be committed yet, so it may not be visible to other txns.
|
|
ULONG m_ulCurrentChangeRow;
|
|
//@cmember Whether or not Isolation Level Chaos is supported
|
|
BOOL m_fChaos;
|
|
//@cmember Whether or not Isolation Level Read Uncommitted is supported
|
|
BOOL m_fReadUncommitted;
|
|
//@cmember Whether or not Isolation Level Read Committed is supported
|
|
BOOL m_fReadCommitted;
|
|
//@cmember Whether or not Isolation Level Repeatable Read is supported
|
|
BOOL m_fRepeatableRead;
|
|
//@cmember Whether or not Isolation Level Serializable is supported
|
|
BOOL m_fSerializable;
|
|
//@cmember A supported isolation level to use for general purposes
|
|
ISOLATIONLEVEL m_fIsoLevel;
|
|
//@cmember Whether or not the current datasource is Microsoft Access
|
|
//this flag is used to decide if we need to wait a few seconds after an update
|
|
//before other connections can see it.
|
|
BOOL m_fOnAccess;
|
|
|
|
//@cmember CTOR
|
|
CTxn(LPWSTR tcName);
|
|
//@cmember Initialization
|
|
virtual BOOL Init();
|
|
//@cmember Termination
|
|
virtual BOOL Terminate();
|
|
//@cmember Gets value to use for next insert
|
|
inline ULONG GetNextRowToInsert(){return g_ulLastActualInsert + 1;};
|
|
//@cmember Gets value to use for next delete
|
|
inline ULONG GetNextRowToDelete(){return g_ulLastActualDelete + 1;};
|
|
//@cmember Copies normally initialized by test framework test case info
|
|
//into the encapsulated object which inherits from CTestCases.
|
|
void CopyTestCaseInfo(CTestCases * pTC);
|
|
//@cmember Inserts the next row into the table, on the given txn
|
|
BOOL Insert(CTxnChgRowset * pTxnChgRowset);
|
|
//@cmember Deletes the next row to delete in the table, on the given txn
|
|
BOOL Delete(CTxnChgRowset * pTxnChgRowset, HROW * phRow = NULL);
|
|
//@cmember Changes the next row to delete in the table to the values
|
|
//based on the next row to insert, on the given txn
|
|
BOOL Change(CTxnChgRowset * pTxnChgRowset);
|
|
//@cmember Tries to find the current inserted row, which may or may not be commited
|
|
inline BOOL FindInsert(CTxnRowset * pRowset)
|
|
{ return pRowset->FindRow(m_ulCurrentInsertRow, NULL);};
|
|
//@cmember Tries to find the current deleted row, which may or may not be commited
|
|
inline BOOL FindDelete(CTxnRowset * pRowset)
|
|
{ return pRowset->FindRow(m_ulCurrentDeleteRow, NULL);};
|
|
//@cmember Tries to find the current Changed row, which may or may not be commited
|
|
inline BOOL FindChange(CTxnRowset * pRowset)
|
|
{ return pRowset->FindRow(m_ulCurrentChangeRow, NULL);};
|
|
//@cmember Starts the txn with the IsoLevel
|
|
HRESULT StartTxn(ITransactionLocal * pITxnLocal, ISOLEVEL IsoLevel);
|
|
//@cmember Releases all rowsets associated with any encapsulated objects
|
|
virtual void ReleaseAllRowsetsAndTxns()=0;
|
|
//@cmember Determines whether or not a new unit of work has begun on txn 1
|
|
BOOL NewUnitOfWork(CTxnChgRowset * pTxnChgRowset, CTxnRowset * pTxnRowset);
|
|
//#ifdef TXNJOIN
|
|
//@cmember Determines whether or not a new unit of work has begun on txn 1
|
|
BOOL NewUnitOfWorkCoord(CTxnChgRowset *pTxnChgRowset, CTxnRowset *pTxnRowset, ITransaction *pITransaction,ITransactionJoin *pITransactionJoin);
|
|
//@cmember Determines whether or not txn 1 is in autocommit mode
|
|
BOOL NoNewUnitOfWorkCoord(CTxnChgRowset *pTxnChgRowset, CTxnRowset *pTxnRowset, ITransaction *pITransaction, BOOL fChange,ITransactionJoin *pITransactionJoin);
|
|
//#endif//TXNJOIN
|
|
//@cmember Determines whether or not the rowset is functional on txn 1
|
|
BOOL RowsetFunctional(CTxnRowset * pTxnRowset);
|
|
//@cmember Determines whether or not the rowset is zombied on txn 1
|
|
BOOL RowsetZombied(CTxnRowset * pTxnRowset, IRowset ** ppIRowset, HROW * phRow, HACCESSOR hAccessor);
|
|
//@cmember Determines whether or not txn 1 is in autocommit mode
|
|
BOOL NoNewUnitOfWork(CTxnChgRowset *pTxnChgRowset, CTxnRowset *pTxnRowset);
|
|
//@cmember Verifies all transaction info from GetTransactionInfo
|
|
BOOL VerifyTxnInfo(ITransaction * pITxn, ISOLEVEL isoLevel, XACTUOW * puow = NULL);
|
|
|
|
};
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @class CUpdateTxn | Base Class for non buffered mode Transaction testing.
|
|
// @base public | CTxn
|
|
//--------------------------------------------------------------------
|
|
class CTxnImmed : public CTxn
|
|
{
|
|
|
|
// @access public
|
|
public:
|
|
|
|
//@cmember CTOR
|
|
CTxnImmed(LPWSTR wszTestCaseName);
|
|
//@cmember Pointer to Rowset object that supports Changes on TXN_1
|
|
CTxnChgRowset * m_pChgRowset1;
|
|
//@cmember Pointer to Rowset object that supports Changes on TXN_2
|
|
CTxnChgRowset * m_pChgRowset2;
|
|
//@cmember Pointer to Rowset object that supports Changes on TXN_3
|
|
CTxnChgRowset * m_pChgRowset3;
|
|
//@cmember Pointer to Read Only Rowset on TXN_1
|
|
CTxnRORowset * m_pRORowset1;
|
|
|
|
//@cmember Initialization
|
|
virtual BOOL Init();
|
|
//@cmember Termination
|
|
virtual BOOL Terminate();
|
|
//@cmember Releases all rowsets associated with any encapsulated objects
|
|
virtual void ReleaseAllRowsetsAndTxns();
|
|
//@cmember Releases all rowsets associated with any encapsulated objects
|
|
virtual void ReleaseAllRowsets();
|
|
|
|
//@cmember Get DBPROP_SUPPORTEDTXNISOLEVELS
|
|
HRESULT GetIsoLevels(ISOLEVEL *pIsoLevel);
|
|
|
|
};
|
|
|
|
|
|
// This structure keeps the numeric value and description of each isolation level
|
|
struct tagIsolation {
|
|
char *pszDesc;
|
|
ULONG ulIsolation;
|
|
};
|
|
|
|
extern tagIsolation g_IsolationList[];
|
|
extern ULONG g_ulTotalIsolations;
|