2025-11-28 00:35:46 +09:00

467 lines
20 KiB
C++

// Start of file MSOmniProvRS.h
// File: MSOmniProvRS.h
//
// This file contains the Declaration of the CMSOmniProvRowset and CMSOmniProvCommand
//
// The following functions have been customized or added for the provider to function:
//
// CMSOmniProvRowset :: GetData - Retrieves data from the rowset's copy of the row...
// CMSOmniProvRowset :: SetSchemaInfo - Creates the rowset column info structure...
// CMSOmniProvRowset :: GetNextRows - Releases rows...
// CMSOmniProvRowset :: GetNextRows - Fetches rows, sequentially, remembering the previous position...
//
#ifndef __CMSOmniProvRowset_H_
#define __CMSOmniProvRowset_H_
#include "resource.h" // main symbols
#include "IRowsetScroll.h" // IRowsetScroll
#include "IRowsetChange.h" // IRowsetChange
#include "RNCP.h" // The ConnectionPoint and IRowsetNotify Proxy class
#include "CDBFile.h"
class CMSOmniProvCommand ;
class CMSOmniProvRowset ;
// CMSOmniProvCommand
class ATL_NO_VTABLE CMSOmniProvCommand :
public CComObjectRootEx<CComSingleThreadModel>, // Single Threaded for the present...
public IAccessorImpl<CMSOmniProvCommand>,
public ICommandTextImpl<CMSOmniProvCommand>,
public ICommandPropertiesImpl<CMSOmniProvCommand>,
public IObjectWithSiteImpl<CMSOmniProvCommand>,
public IConvertTypeImpl<CMSOmniProvCommand>,
public IColumnsInfoImpl<CMSOmniProvCommand>
{
public:
BEGIN_COM_MAP(CMSOmniProvCommand)
COM_INTERFACE_ENTRY(ICommand)
COM_INTERFACE_ENTRY(IObjectWithSite)
COM_INTERFACE_ENTRY(IAccessor)
COM_INTERFACE_ENTRY(ICommandProperties)
COM_INTERFACE_ENTRY2(ICommandText, ICommand)
COM_INTERFACE_ENTRY(IColumnsInfo)
COM_INTERFACE_ENTRY(IConvertType)
END_COM_MAP()
// ICommand
public:
static ATLCOLUMNINFO* GetColumnInfo(CMSOmniProvCommand* pv, DBORDINAL* pcInfo);
HRESULT FinalConstruct()
{
HRESULT hr = CConvertHelper::FinalConstruct();
if (FAILED (hr))
return hr;
hr = IAccessorImpl<CMSOmniProvCommand>::FinalConstruct();
if (FAILED(hr))
return hr;
return CUtlProps<CMSOmniProvCommand>::FInit();
}
void FinalRelease()
{
IAccessorImpl<CMSOmniProvCommand>::FinalRelease();
}
HRESULT WINAPI Execute(IUnknown * pUnkOuter, REFIID riid, DBPARAMS * pParams,
DBROWCOUNT * pcRowsAffected, IUnknown ** ppRowset);
BEGIN_PROPSET_MAP(CMSOmniProvCommand)
BEGIN_PROPERTY_SET(DBPROPSET_ROWSET)
PROPERTY_INFO_ENTRY_EX(IAccessor,VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(IColumnsInfo, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(IConvertType, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(IRowset, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(IRowsetIdentity,VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(IRowsetInfo, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(IRowsetChange, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(UPDATABILITY, VT_I4, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_DELETE | DBPROPVAL_UP_INSERT, 0)
PROPERTY_INFO_ENTRY_EX(OWNINSERT, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(OWNUPDATEDELETE, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(REMOVEDELETED, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(IRowsetScroll, VT_BOOL,DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(CANFETCHBACKWARDS,VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(CANHOLDROWS, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(CANSCROLLBACKWARDS, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(IRowsetLocate, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(BOOKMARKS, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE , VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(BOOKMARKSKIPPED,VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(BOOKMARKTYPE, VT_I4, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, DBPROPVAL_BMK_NUMERIC, 0)
PROPERTY_INFO_ENTRY_EX(LITERALBOOKMARKS, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(ORDEREDBOOKMARKS, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_VALUE(LITERALIDENTITY,VARIANT_TRUE)
PROPERTY_INFO_ENTRY_VALUE(STRONGIDENTITY,VARIANT_TRUE)
PROPERTY_INFO_ENTRY_VALUE(NOTIFICATIONPHASES, DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER |DBPROPVAL_NP_FAILEDTODO | DBPROPVAL_NP_DIDEVENT)
PROPERTY_INFO_ENTRY_EX(NOTIFYROWDELETE, VT_I4, DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER | DBPROPVAL_NP_FAILEDTODO | DBPROPVAL_NP_DIDEVENT, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(NOTIFYROWINSERT, VT_I4, DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER | DBPROPVAL_NP_FAILEDTODO | DBPROPVAL_NP_DIDEVENT, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(NOTIFYCOLUMNSET, VT_I4, DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER | DBPROPVAL_NP_FAILEDTODO | DBPROPVAL_NP_DIDEVENT, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(NOTIFYROWSETFETCHPOSITIONCHANGE, VT_I4, DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER | DBPROPVAL_NP_FAILEDTODO | DBPROPVAL_NP_DIDEVENT, VARIANT_TRUE, 0)
PROPERTY_INFO_ENTRY_EX(SERVERCURSOR, VT_BOOL, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ , VARIANT_TRUE, 0)
END_PROPERTY_SET(DBPROPSET_ROWSET)
END_PROPSET_MAP()
};
typedef CDBFile dummyStore;
class ATL_NO_VTABLE CMSOmniProvRowset :
public CRowsetImpl <CMSOmniProvRowset, dummyStore, CMSOmniProvCommand, CAtlArray<dummyStore>, CSimpleRow, IRowsetScrollImpl<CMSOmniProvRowset> > ,
public IMyRowsetChangeImpl<CMSOmniProvRowset, dummyStore>,
public CProxyIRowsetNotify< CMSOmniProvRowset >,
public IConnectionPointContainerImpl<CMSOmniProvRowset>
{
public:
typedef CRowsetImpl <CMSOmniProvRowset, dummyStore, CMSOmniProvCommand, CAtlArray<dummyStore>, CSimpleRow, IRowsetScrollImpl<CMSOmniProvRowset> > _OmniProvBaseClass;
BEGIN_COM_MAP(CMSOmniProvRowset)
COM_INTERFACE_ENTRY(IRowsetLocate)
COM_INTERFACE_ENTRY(IRowsetScroll)
COM_INTERFACE_ENTRY(IRowsetChange)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
COM_INTERFACE_ENTRY_CHAIN(_OmniProvBaseClass)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CMSOmniProvRowset)
CONNECTION_POINT_ENTRY(IID_IRowsetNotify)
END_CONNECTION_POINT_MAP()
public:
static ATLCOLUMNINFO* GetColumnInfo(CMSOmniProvRowset* pv, DBORDINAL* pNumCols);
BOOL CheckTable(TCHAR* szTblName);
HRESULT Execute(DBPARAMS * pParams, DBROWCOUNT* pcRowsAffected);
void CreateColInfo();
void AllocateProxyBuffers();
HRESULT GetDataSource(_bstr_t &m_bstrLoc);
ATLCOLUMNINFO * GetSchemaInfo(DBORDINAL * pNumCols);
// All the member variables
DBORDINAL m_cCols; // Number of columns represented in m_prgColInfo
CDBFile m_DBFile; // The Storage class
ATLCOLUMNINFO * m_prgColInfo; // Each rowset will have its set of column infos with or without bookmarks
// The Constructor
CMSOmniProvRowset()
{
m_prgColInfo = NULL;
}
// The Destructor
~CMSOmniProvRowset()
{
if(m_prgColInfo)
{
delete [] m_prgColInfo;
m_prgColInfo = NULL;
}
}
// CMSOmniProvRowset :: SetSchemaInfo
// This function copies the final column info to the rowset class
// Usually called from the Execute method as that is when the columns will be known
// (bookmark + columns selected)
void SetSchemaInfo(ATLCOLUMNINFO * prgColInfo, DBORDINAL cCols)
{
m_cCols = cCols;
m_prgColInfo = new ATLCOLUMNINFO[cCols];
// Copy the information from the columninfo passed in. This is possible because
// we know that there are no pointers in the structure.
for (DBORDINAL i = 0; i < cCols; i++)
m_prgColInfo[i] = prgColInfo[i];
}
// CMSOmniProvRowset :: Getdata
// Retrieves data from the rowset's copy of the row.
STDMETHOD(GetData)(HROW hRow,
HACCESSOR hAccessor,
void *pDstData)
{
ATLTRACE2(atlTraceDBProvider, 0, "IRowsetImpl::GetData\n");
if (pDstData == NULL)
return E_INVALIDARG;
HRESULT hr = S_OK;
//CSimpleRow* pHRow = (CSimpleRow*)hRow;
// 2.0
CSimpleRow* pHRow = NULL;
if (hRow == NULL || (pHRow = (m_rgRowHandles.Lookup(hRow))->m_value ) == NULL)
return DB_E_BADROWHANDLE;
_BindType* pBinding;
void* pSrcData;
DBORDINAL cCols;
ATLCOLUMNINFO* pColInfo;
pBinding = m_rgBindings.Lookup(hAccessor)->m_value;
if (pBinding == NULL)
return DB_E_BADACCESSORHANDLE;
pColInfo = GetColumnInfo(this, &cCols);
CRow *pDataRow = NULL;
// When Client perform a GetData without performing a GetNextRows( )
if(pHRow->m_iRowset >= m_DBFile.m_Rows.GetCount())
return DB_E_DELETEDROW;
pDataRow = m_DBFile.m_Rows[pHRow->m_iRowset];
// Fetch data in the proxy buffer if it hasn't already been fetched
pDataRow->GetProxyData(pColInfo, cCols);
// assign source buffer to the proxy buffer
pSrcData = pDataRow->m_pbProxyData;
for (ULONG iBind =0; iBind < pBinding->cBindings; iBind++)
{
DBBINDING* pBindCur = &(pBinding->pBindings[iBind]);
DBORDINAL iColInfo;
for (iColInfo = 0;
iColInfo < cCols && pBindCur->iOrdinal != pColInfo[iColInfo].iOrdinal;
iColInfo++);
if (iColInfo == cCols)
return DB_E_BADORDINAL;
ATLCOLUMNINFO* pColCur = &(pColInfo[iColInfo]);
// Ordinal found at iColInfo
BOOL bProvOwn = pBindCur->dwMemOwner == DBMEMOWNER_PROVIDEROWNED;
bProvOwn;
DBSTATUS dbStat = DBSTATUS_S_OK;
// If the provider's field is NULL, we can optimize this situation,
// set the fields to 0 and continue.
if (dbStat == DBSTATUS_S_ISNULL)
{
if (pBindCur->dwPart & DBPART_STATUS)
*((DBSTATUS*)((BYTE*)(pDstData) + pBindCur->obStatus)) = dbStat;
if (pBindCur->dwPart & DBPART_LENGTH)
*((DBLENGTH*)((BYTE*)(pDstData) + pBindCur->obLength)) = 0;
if (pBindCur->dwPart & DBPART_VALUE)
*((BYTE*)(pDstData) + pBindCur->obValue) = NULL;
continue;
}
DBLENGTH cbDst = pBindCur->cbMaxLen;
DBLENGTH cbCol;
BYTE* pSrcTemp;
void *pvData = NULL;
void * pvTmpData = NULL;
if (bProvOwn && pColCur->wType == pBindCur->wType)
{
pSrcTemp = ((BYTE*)(pSrcData) + pColCur->cbOffset);
}
else
{
BYTE* pDstTemp = (BYTE*)pDstData + pBindCur->obValue;
switch (pColCur->wType)
{
case DBTYPE_STR:
cbCol = lstrlenA((LPSTR)(((BYTE*)pSrcData) + pColCur->cbOffset));
break;
case DBTYPE_WSTR:
case DBTYPE_BSTR:
cbCol = lstrlenW((LPWSTR)(((BYTE*)pSrcData) + pColCur->cbOffset)) * sizeof(WCHAR);
break;
// The char ptr case
case DBTYPE_STR | DBTYPE_BYREF:
pvData = (((BYTE*)pSrcData) + pColCur->cbOffset);
cbCol =lstrlenA(*(char**)pvData);
break;
default:
cbCol = pColCur->ulColumnSize;
break;
}
if (pBindCur->dwPart & DBPART_VALUE)
{
hr = m_spConvert->DataConvert(pColCur->wType, pBindCur->wType,
cbCol, &cbDst, (BYTE*)(pSrcData) + pColCur->cbOffset,
pDstTemp, pBindCur->cbMaxLen, dbStat, &dbStat,
pBindCur->bPrecision, pBindCur->bScale,0);
}
}
if (pBindCur->dwPart & DBPART_LENGTH)
*(DBBYTEOFFSET*)((BYTE*)pDstData + pBindCur->obLength) = cbDst;
if (pBindCur->dwPart & DBPART_STATUS)
*((DBSTATUS*)((BYTE*)(pDstData) + pBindCur->obStatus)) = dbStat;
if (FAILED(hr))
return hr;
}
return hr;
}
// CMSOmniProvRowset :: ReleaseRows
// Releases rows.
STDMETHOD(ReleaseRows)(DBCOUNTITEM cRows,
const HROW rghRows[],
DBROWOPTIONS rgRowOptions[],
DBREFCOUNT rgRefCounts[],
DBROWSTATUS rgRowStatus[])
{
HRESULT hr = _OmniProvBaseClass::ReleaseRows(
cRows,
rghRows,
rgRowOptions,
rgRefCounts,
rgRowStatus);
if(FAILED(Fire_OnRowChangeMy(this, cRows, rghRows, DBREASON_ROW_RELEASE, DBEVENTPHASE_DIDEVENT, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROW_RELEASE in DBEVENTPHASE_DIDEVENT phase\n");
return hr;
}
// CMSOmniProvRowset :: GetNextRows
// Fetches rows, sequentially, remembering the previous position...
STDMETHOD(GetNextRows)(HCHAPTER /*hReserved*/,
DBROWOFFSET lRowsOffset,
DBROWCOUNT cRows,
DBCOUNTITEM *pcRowsObtained,
HROW **prghRows)
{
DBROWOFFSET lTmpRows = lRowsOffset;
ATLTRACE2(atlTraceDBProvider, 0, "IRowsetImpl::GetNextRows\n");
HRESULT hrEvent;
CMSOmniProvRowset* pT = (CMSOmniProvRowset*) this;
CMSOmniProvRowset::ObjectLock cab(pT);
if(FAILED(hrEvent = Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_OKTODO, TRUE)))
{
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_OKTODO phase\n");
if(hrEvent==S_FALSE)
return DB_E_CANCELED;
}
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_ABOUTTODO, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_ABOUTTODO phase\n");
if (pcRowsObtained != NULL)
*pcRowsObtained = 0;
if (prghRows == NULL || pcRowsObtained == NULL)\
{
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_FAILEDTODO, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_FAILEDTODO phase\n");
return E_INVALIDARG;
}
if (cRows == 0)
{
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_SYNCHAFTER, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_SYNCHAFTER phase\n");
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_DIDEVENT, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_DIDEVENT phase\n");
return S_OK;
}
HRESULT hr = S_OK;
if (lRowsOffset < 0 && !m_bCanScrollBack)
{
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_FAILEDTODO, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_FAILEDTODO phase\n");
return DB_E_CANTSCROLLBACKWARDS;
}
if (cRows < 0 && !m_bCanFetchBack)
{
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_FAILEDTODO, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_FAILEDTODO phase\n");
return DB_E_CANTFETCHBACKWARDS;
}
// Calculate # of rows in set and the base fetch position. If the rowset
// is at its head position, then lRowOffset < 0 means moving from the BACK
// of the rowset and not the front.
DBROWOFFSET cRowsInSet = pT->m_DBFile.m_Rows.GetCount();
if (((lRowsOffset == LONG_MIN) && (cRowsInSet != LONG_MIN))
|| (AbsVal(lRowsOffset)) > cRowsInSet ||
(AbsVal(lRowsOffset) == cRowsInSet && lRowsOffset < 0 && cRows < 0) ||
(AbsVal(lRowsOffset) == cRowsInSet && lRowsOffset > 0 && cRows > 0))
{
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_FAILEDTODO, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_FAILEDTODO phase\n");
return DB_S_ENDOFROWSET;
}
// In the case where the user is moving backwards after moving forwards,
// we do not wrap around to the end of the rowset.
if ((m_iRowset == 0 && !m_bReset && cRows < 0) ||
(((LONG)m_iRowset + lRowsOffset) > cRowsInSet) ||
(m_iRowset == (DWORD)cRowsInSet && lRowsOffset >= 0 && cRows > 0))
{
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_FAILEDTODO, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_FAILEDTODO phase\n");
return DB_S_ENDOFROWSET;
}
// Note, if m_bReset, m_iRowset must be 0
if (lRowsOffset < 0 && m_bReset)
{
ATLASSERT(m_iRowset == 0);
m_iRowset = cRowsInSet;
}
int iStepSize = cRows >= 0 ? 1 : -1;
// If cRows == LONG_MIN, we can't use ABS on it. Therefore, we reset it
// to a value just greater than cRowsInSet
if (cRows == LONG_MIN && cRowsInSet != LONG_MIN)
cRows = cRowsInSet + 2; // set the value to something we can deal with
else
cRows = AbsVal(cRows);
if (iStepSize < 0 && m_iRowset == 0 && m_bReset && lRowsOffset <= 0)
m_iRowset = cRowsInSet;
lRowsOffset += m_iRowset;
*pcRowsObtained = 0;
CComHeapPtr<HROW> amr;
if (*prghRows == NULL)
{
DBROWCOUNT cHandlesToAlloc = (cRows > cRowsInSet) ? cRowsInSet : cRows;
if (iStepSize == 1 && (cRowsInSet - lRowsOffset) < cHandlesToAlloc)
cHandlesToAlloc = cRowsInSet - lRowsOffset;
if (iStepSize == -1 && lRowsOffset < cHandlesToAlloc)
cHandlesToAlloc = lRowsOffset;
*prghRows = (HROW*)CoTaskMemAlloc((cHandlesToAlloc) * sizeof(HROW*));
amr.Attach(*prghRows);
}
if (*prghRows == NULL)
{
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_FAILEDTODO, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_FAILEDTODO phase\n");
return E_OUTOFMEMORY;
}
while ((lRowsOffset >= 0 && cRows != 0) &&
((lRowsOffset < cRowsInSet) || (lRowsOffset <= cRowsInSet && iStepSize < 0)))
{
// cRows > cRowsInSet && iStepSize < 0
if (lRowsOffset == 0 && cRows > 0 && iStepSize < 0)
break;
// in the case where we have iStepSize < 0, move the row back
// further because we want the previous row
DBROWOFFSET lRow = lRowsOffset;
if ((lRowsOffset == 0) && (lTmpRows == 0) && (iStepSize < 0))
lRow = cRowsInSet;
if (iStepSize < 0)
lRow += iStepSize;
hr = pT->CreateRow(lRow, *pcRowsObtained, *prghRows);
if (FAILED(hr))
{
RefRows(*pcRowsObtained, *prghRows, NULL, NULL, FALSE);
for (ULONG iRowDel = 0; iRowDel < *pcRowsObtained; iRowDel++)
*prghRows[iRowDel] = NULL;
*pcRowsObtained = 0;
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_FAILEDTODO, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_FAILEDTODO phase\n");
return hr;
}
cRows--;
lRowsOffset += iStepSize;
}
if ((lRowsOffset >= cRowsInSet && cRows) || (lRowsOffset < 0 && cRows) ||
(lRowsOffset == 0 && cRows > 0 && iStepSize < 0))
hr = DB_S_ENDOFROWSET;
m_iRowset = lRowsOffset;
if (SUCCEEDED(hr))
amr.Detach();
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_SYNCHAFTER, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_SYNCHAFTER phase\n");
if(FAILED(Fire_OnRowsetChangeMy(this, DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_DIDEVENT, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROWSET_FETCHPOSITIONCHANGE in DBEVENTPHASE_DIDEVENT phase\n");
if(FAILED(Fire_OnRowChangeMy(this, cRows, *prghRows, DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TRUE)))
ATLTRACE2(atlTraceDBProvider, 0, "Failed to Fire DBREASON_ROW_ACTIVATE in DBEVENTPHASE_DIDEVENT phase\n");
return hr;
}
};
#endif //__CMSOmniProvRowset_H_
// End of file MSOmniProvRS.h